MIPS: Changed "marked" nops to use sll(zero_reg, at, type).
authordanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 4 Oct 2012 09:46:50 +0000 (09:46 +0000)
committerdanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 4 Oct 2012 09:46:50 +0000 (09:46 +0000)
We use marking bits in nops (in the 'sa' field) for debug markers, and for some IC stuff. A normal NOP in mips is sll(zero_reg, zero_reg, 0), where the 0 is a 5 bit immediate field in 'sa'.

See enum NopMarkerTypes at around line 654 of assembler-mips.h

The problem is that these markers use encodings that are reserved for the 'ssnop' and 'ehb' instructions. These are instructions used for hazard barriers.

It does not break anything, but it will slow things down a little bit as some pipeline stages are cleared, etc.

This commit changes the "marked" NOPs to sll(zero_reg, at, type) instructions, which is also a NOP operation on MIPS.

BUG=
TEST=

Review URL: https://codereview.chromium.org/10990110
Patch from Akos Palfi <palfia@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12657 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/mips/assembler-mips.cc
src/mips/assembler-mips.h

index 801ca2c..a4563a6 100644 (file)
@@ -580,17 +580,20 @@ bool Assembler::IsNop(Instr instr, unsigned int type) {
   // See Assembler::nop(type).
   ASSERT(type < 32);
   uint32_t opcode = GetOpcodeField(instr);
+  uint32_t function = GetFunctionField(instr);
   uint32_t rt = GetRt(instr);
-  uint32_t rs = GetRs(instr);
+  uint32_t rd = GetRd(instr);
   uint32_t sa = GetSa(instr);
 
-  // nop(type) == sll(zero_reg, zero_reg, type);
-  // Technically all these values will be 0 but
-  // this makes more sense to the reader.
+  // Traditional mips nop == sll(zero_reg, zero_reg, 0)
+  // When marking non-zero type, use sll(zero_reg, at, type)
+  // to avoid use of mips ssnop and ehb special encodings
+  // of the sll instruction.
 
-  bool ret = (opcode == SLL &&
-              rt == static_cast<uint32_t>(ToNumber(zero_reg)) &&
-              rs == static_cast<uint32_t>(ToNumber(zero_reg)) &&
+  Register nop_rt_reg = (type == 0) ? zero_reg : at;
+  bool ret = (opcode == SPECIAL && function == SLL &&
+              rd == static_cast<uint32_t>(ToNumber(zero_reg)) &&
+              rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) &&
               sa == type);
 
   return ret;
index 7163770..ee4daad 100644 (file)
@@ -663,10 +663,13 @@ class Assembler : public AssemblerBase {
     FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
   };
 
-  // Type == 0 is the default non-marking type.
+  // Type == 0 is the default non-marking nop. For mips this is a
+  // sll(zero_reg, zero_reg, 0). We use rt_reg == at for non-zero
+  // marking, to avoid conflict with ssnop and ehb instructions.
   void nop(unsigned int type = 0) {
     ASSERT(type < 32);
-    sll(zero_reg, zero_reg, type, true);
+    Register nop_rt_reg = (type == 0) ? zero_reg : at;
+    sll(zero_reg, nop_rt_reg, type, true);
   }