Make the operand size reflect the size specifier on the operand tags, and implement NEG
authorGabe Black <gblack@eecs.umich.edu>
Mon, 23 Jul 2007 01:07:49 +0000 (01:07 +0000)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 23 Jul 2007 01:07:49 +0000 (01:07 +0000)
--HG--
extra : convert_revision : da73ed6820d57f083c18f44b2fa868fc0976dd16

src/arch/x86/isa/decoder/one_byte_opcodes.isa
src/arch/x86/isa/decoder/two_byte_opcodes.isa
src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
src/arch/x86/isa/macroop.isa
src/arch/x86/isa/specialize.isa

index b28f2029c81d67f4cbff0b74090a9ec59dad08ea..9a70e9f4f0a7d66bf3151050ccefe846ddfe7790 100644 (file)
@@ -72,7 +72,7 @@
             default: MultiInst::ADD(OPCODE_OP_BOTTOM3,
                                     [Eb,Gb], [Ev,Gv],
                                     [Gb,Eb], [Gv,Ev],
-                                    [rAl,Ib], [rAx,Iz]);
+                                    [rAb,Ib], [rAv,Iz]);
         }
         0x01: decode OPCODE_OP_BOTTOM3 {
             0x6: decode MODE_SUBMODE {
@@ -85,7 +85,7 @@
             default: MultiInst::OR(OPCODE_OP_BOTTOM3,
                                    [Eb,Gb], [Ev,Gv],
                                    [Gb,Eb], [Gv,Ev],
-                                   [rAl,Ib], [rAx,Iz]);
+                                   [rAb,Ib], [rAv,Iz]);
         }
         0x02: decode OPCODE_OP_BOTTOM3 {
             0x6: decode MODE_SUBMODE {
@@ -99,7 +99,7 @@
             default: MultiInst::ADC(OPCODE_OP_BOTTOM3,
                                     [Eb,Gb], [Ev,Gv],
                                     [Gb,Eb], [Gv,Ev],
-                                    [rAl,Ib], [rAx,Iz]);
+                                    [rAb,Ib], [rAv,Iz]);
         }
         0x03: decode OPCODE_OP_BOTTOM3 {
             0x6: decode MODE_SUBMODE {
             default: MultiInst::SBB(OPCODE_OP_BOTTOM3,
                                     [Eb,Gb], [Ev,Gv],
                                     [Gb,Eb], [Gv,Ev],
-                                    [rAl,Ib], [rAx,Iz]);
+                                    [rAb,Ib], [rAv,Iz]);
         }
         0x04: decode OPCODE_OP_BOTTOM3 {
             0x6: M5InternalError::error(
             default: MultiInst::AND(OPCODE_OP_BOTTOM3,
                                     [Eb,Gb], [Ev,Gv],
                                     [Gb,Eb], [Gv,Ev],
-                                    [rAl,Ib], [rAx,Iz]);
+                                    [rAb,Ib], [rAv,Iz]);
         }
         0x05: decode OPCODE_OP_BOTTOM3 {
             0x6: M5InternalError::error(
             default: MultiInst::SUB(OPCODE_OP_BOTTOM3,
                                     [Eb,Gb], [Ev,Gv],
                                     [Gb,Eb], [Gv,Ev],
-                                    [rAl,Ib], [rAx,Iz]);
+                                    [rAb,Ib], [rAv,Iz]);
         }
         0x06: decode OPCODE_OP_BOTTOM3 {
             0x6: M5InternalError::error(
             default: MultiInst::XOR(OPCODE_OP_BOTTOM3,
                                     [Eb,Gb], [Ev,Gv],
                                     [Gb,Eb], [Gv,Ev],
-                                    [rAl,Ib], [rAx,Iz]);
+                                    [rAb,Ib], [rAv,Iz]);
         }
         0x07: decode OPCODE_OP_BOTTOM3 {
             0x6: M5InternalError::error(
             default: MultiInst::CMP(OPCODE_OP_BOTTOM3,
                                     [Eb,Gb], [Ev,Gv],
                                     [Gb,Eb], [Gv,Ev],
-                                    [rAl,Ib], [rAx,Iz]);
+                                    [rAb,Ib], [rAv,Iz]);
         }
         0x08: decode MODE_SUBMODE {
             0x0: M5InternalError::error (
                 default: bound_Gv_Ma();
             }
             0x3: decode MODE_SUBMODE {
-                0x0: Inst::MOVSXD(Gv,Ed);
+                //The second operand should really be of size "d", but it's
+                //set to "v" in order to have a consistent register size.
+                //This shouldn't affect behavior.
+                0x0: Inst::MOVSXD(Gv,Ev);
                 default: arpl_Ew_Gw();
             }
             0x4: M5InternalError::error(
             0x7: cmps_Yv_Xv();
         }
         0x15: decode OPCODE_OP_BOTTOM3 {
-            0x0: Inst::TEST(rAl,Ib);
-            0x1: Inst::TEST(rAX,Iz);
+            0x0: Inst::TEST(rAb,Ib);
+            0x1: Inst::TEST(rAv,Iz);
             0x2: stos_Yb_Al();
             0x3: stos_Yv_rAX();
             0x4: lods_Al_Xb();
                 {{"Tried to execute the rep/repe prefix!"}});
             0x4: hlt();
             0x5: cmc();
-            0x6: group3_Eb();
-            0x7: group3_Ev();
+            //0x6: group3_Eb();
+            0x6: decode MODRM_REG {
+                0x0: test_Eb_Iz();
+                0x1: test_Eb_Iz();
+                0x2: not_Eb();
+                0x3: Inst::NEG(Eb);
+                0x4: mul_Eb();
+                0x5: imul_Eb();
+                0x6: div_Eb();
+                0x7: idiv_Eb();
+            }
+            //0x7: group3_Ev();
+            0x7: decode MODRM_REG {
+                0x0: test_Ev_Iz();
+                0x1: test_Ev_Iz();
+                0x2: not_Ev();
+                0x3: Inst::NEG(Ev);
+                0x4: mul_Ev();
+                0x5: imul_Ev();
+                0x6: div_Ev();
+                0x7: idiv_Ev();
+            }
         }
         0x1F: decode OPCODE_OP_BOTTOM3 {
             0x0: clc();
index e5631d37bbd9d39661e90fb17371e24f328752eb..3bda044c86fb83d4c17fe758f3b1b2b52fe3467f 100644 (file)
                 0x3: btr_Ev_Gv();
                 0x4: lfs_Gz_Mp();
                 0x5: lgs_Gz_Mp();
-                0x6: Inst::MOVZX_B(Gv,Eb);
-                0x7: Inst::MOVZX_W(Gv,Ew);
+                //The size of the second operand in these instructions should
+                //really be "b" or "w", but it's set to v in order to have a
+                //consistent register size. This shouldn't affect behavior.
+                0x6: Inst::MOVZX_B(Gv,Ev);
+                0x7: Inst::MOVZX_W(Gv,Ev);
             }
             0x17: decode OPCODE_OP_BOTTOM3 {
                 0x0: jmpe_Jz(); // IA-64?
                 0x3: btc_Ev_Gv();
                 0x4: bsf_Gv_Ev();
                 0x5: bsr_Gv_Ev();
-                0x6: Inst::MOVSX_B(Gv,Eb);
-                0x7: Inst::MOVSX_W(Gv,Ew);
+                //The size of the second operand in these instructions should
+                //really be "b" or "w", but it's set to v in order to have a
+                //consistent register size. This shouldn't affect behavior.
+                0x6: Inst::MOVSX_B(Gv,Ev);
+                0x7: Inst::MOVSX_W(Gv,Ev);
             }
             0x18: decode OPCODE_OP_BOTTOM3 {
                 0x0: holder();
index 05aa6cd69e69c0ddd707263bd52b4dce2f8eee46..e637251d24916a69cb8d7ae32d2087f1d905efa9 100644 (file)
@@ -277,6 +277,26 @@ def macroop SBB_P_R
     sbb t1, t1, reg
     st t1, ds, [scale, index, base], disp
 };
+
+def macroop NEG_R
+{
+    sub reg, t0, reg, flags=(CF,OF,SF,ZF,AF,PF)
+};
+
+def macroop NEG_M
+{
+    ld t1, ds, [scale, index, base], disp
+    sub t1, t0, t1, flags=(CF,OF,SF,ZF,AF,PF)
+    st t1, ds, [scale, index, base], disp
+};
+
+def macroop NEG_P
+{
+    rdip t7
+    ld t1, ds, [0, t0, t7], disp
+    sub t1, t0, t1, flags=(CF,OF,SF,ZF,AF,PF)
+    st t1, ds, [0, t0, t7], disp
+};
 '''
 #let {{
 #    class ADC(Inst):
index 8453a4fe9322212cc31eee4a4fe8ba5f63753c60..4131246a4fc03c57be216711fc908cb8bb0db2f8 100644 (file)
@@ -196,18 +196,34 @@ let {{
             self.regUsed = False
             self.regm = "0"
             self.regmUsed = False
+            self.size = None
             self.addressSize = "ADDRSIZE"
             self.dataSize = "OPSIZE"
             self.stackSize = "STACKSIZE"
             self.doModRM = False
 
         def getAllocator(self):
+            if self.size == 'b':
+                self.dataSize = 1
+            elif self.size == 'd':
+                self.dataSize = 4
+            elif self.size == 'q':
+                self.dataSize = 8
+            elif self.size == 'v':
+                self.dataSize = "OPSIZE"
+            elif self.size == 'w':
+                self.dataSize = 2
+            elif self.size == 'z':
+                self.dataSize = "((OPSIZE == 8) ? 4 : OPSIZE)"
+            elif self.size:
+                raise Exception, "Unrecognized size type %s!" % self.size
             return '''EmulEnv(%(reg)s,
                               %(regm)s,
                               %(dataSize)s,
                               %(addressSize)s,
                               %(stackSize)s)''' % \
                 self.__dict__
+
         def addReg(self, reg):
             if not self.regUsed:
                 self.reg = reg
@@ -217,6 +233,13 @@ let {{
                 self.regmUsed = True
             else:
                 raise Exception, "EmulEnv is out of register specialization spots."
+        def setSize(self, size):
+            if not self.size:
+                self.size = size
+            else:
+                if self.size is not size:
+                    raise Exception, "Conflicting register sizes %s and %s!" %\
+                        (self.size, size)
 }};
 
 let {{
index 5165ea206cfbc39e78351c84fa90d5b87ac098d6..a45c6e80f74752740a906dc4dc86d0549c623754 100644 (file)
@@ -114,7 +114,8 @@ let {{
             self.reg = match.group("reg")
             self.tag = match.group("tag")
             self.size = match.group("size")
-            self.rsize = match.group("rsize")
+            if not self.size:
+                self.size = match.group("rsize")
 
     ModRMRegIndex = "(MODRM_REG | (REX_R << 3))"
     ModRMRMIndex = "(MODRM_RM | (REX_B << 3))"
@@ -129,6 +130,10 @@ let {{
             opType = OpType(opTypes[0])
             opTypes.pop(0)
 
+            if opType.tag not in ("I", "J"):
+                if opType.size:
+                    env.setSize(opType.size)
+
             if opType.reg:
                 #Figure out what to do with fixed register operands
                 #This is the index to use, so we should stick it some place.
@@ -136,13 +141,6 @@ let {{
                     env.addReg("INTREG_R%sX | (REX_B << 3)" % opType.reg)
                 else:
                     env.addReg("INTREG_R%s | (REX_B << 3)" % opType.reg)
-                if opType.size:
-                    if opType.rsize in ("l", "h", "b"):
-                        print "byte"
-                    elif opType.rsize == "x":
-                        print "word"
-                    else:
-                        print "Didn't recognize fixed register size %s!" % opType.rsize
                 Name += "_R"
             elif opType.tag == "B":
                 # This refers to registers whose index is encoded as part of the opcode