Fixed the distinction between far and near versions of jmp, call and ret. Implemented...
authorGabe Black <gblack@eecs.umich.edu>
Sat, 21 Jul 2007 06:16:03 +0000 (23:16 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Sat, 21 Jul 2007 06:16:03 +0000 (23:16 -0700)
--HG--
extra : convert_revision : fcb06189ff213e82da16ac43231feb308cb3a285

src/arch/x86/isa/decoder/one_byte_opcodes.isa
src/arch/x86/isa/insts/control_transfer/call.py
src/arch/x86/isa/insts/control_transfer/jump.py
src/arch/x86/isa/insts/data_transfer/stack_operations.py
src/arch/x86/isa/insts/rotate_and_shift/rotate.py
src/arch/x86/isa/insts/rotate_and_shift/shift.py
src/arch/x86/isa/microops/regop.isa

index 2c2d687856a25b8caa1edb85cfede0a0f9480b42..329a03f408620fc461198319168c388d76a417aa 100644 (file)
             0x1: cwd_or_cdq_or_cqo_rAX_rDX();
             0x2: decode MODE_SUBMODE {
                 0x0: Inst::UD2();
-                default: call_Ap();
+                default: call_far_Ap();
             }
             0x3: fwait(); //aka wait
             0x4: pushf_Fv();
         0x18: decode OPCODE_OP_BOTTOM3 {
             //0x0: group2_Eb_Ib();
             0x0: decode MODRM_REG {
-                0x0: rol_Eb_Ib();
-                0x1: ror_Eb_Ib();
+                0x0: Inst::ROL(Eb,Ib);
+                0x1: Inst::ROR(Eb,Ib);
                 0x2: rcl_Eb_Ib();
                 0x3: rcr_Eb_Ib();
                 0x4: Inst::SAL(Eb,Ib);
-                0x5: shr_Eb_Ib();
+                0x5: Inst::SHR(Eb,Ib);
                 0x6: Inst::SAL(Eb,Ib);
-                0x7: sar_Eb_Ib();
+                0x7: Inst::SAR(Eb,Ib);
             }
             //0x1: group2_Ev_Ib();
             0x1: decode MODRM_REG {
-                0x0: rol_Ev_Ib();
-                0x1: ror_Ev_Ib();
+                0x0: Inst::ROL(Ev,Ib);
+                0x1: Inst::ROR(Ev,Ib);
                 0x2: rcl_Ev_Ib();
                 0x3: rcr_Ev_Ib();
                 0x4: Inst::SAL(Ev,Ib);
-                0x5: shr_Ev_Ib();
+                0x5: Inst::SHR(Ev,Ib);
                 0x6: Inst::SAL(Ev,Ib);
-                0x7: sar_Ev_Ib();
+                0x7: Inst::SAR(Ev,Ib);
             }
             0x2: ret_near_Iw();
             0x3: Inst::RET_NEAR();
             0x1: Inst::JMP(Jz);
             0x2: decode MODE_SUBMODE {
                 0x0: Inst::UD2();
-                default: jmp_Ap();
+                default: jmp_far_Ap();
             }
             0x3: Inst::JMP(Jb);
             0x4: in_Al_Dx();
             0x3: sti();
             0x4: cld();
             0x5: std();
-            //0x6: group4();
-            0x6: decode MODRM_REG {
-                0x0: Inst::INC(Eb);
-                0x1: Inst::DEC(Eb);
-                default: Inst::UD2();
-            }
-            //0x7: group5();
-            0x7: decode MODRM_REG {
-                0x0: Inst::INC(Ev);
-                0x1: Inst::DEC(Ev);
-                0x2: call_Ev();
-                0x3: call_Mp();
-                0x4: jmp_Ev();
-                0x5: jmp_Mp();
-                0x6: push_Ev();
-                0x7: Inst::UD2();
+            format Inst {
+                //0x6: group4();
+                0x6: decode MODRM_REG {
+                    0x0: INC(Eb);
+                    0x1: DEC(Eb);
+                    default: UD2();
+                }
+                //0x7: group5();
+                0x7: decode MODRM_REG {
+                    0x0: INC(Ev);
+                    0x1: DEC(Ev);
+                    0x2: CALL_NEAR(Ev);
+                    0x3: WarnUnimpl::call_far_Mp();
+                    0x4: JMP(Ev);
+                    0x5: WarnUnimpl::jmp_far_Mp();
+                    0x6: PUSH(Ev);
+                    0x7: UD2();
+                }
             }
         }
     }
index c40080d855d72fc1723faa7c5d070b3856cc6a00..c5bb66e583b12b2d8051a17f844c25ba13582a31 100644 (file)
@@ -59,11 +59,46 @@ def macroop CALL_NEAR_I
     # Make the default data size of calls 64 bits in 64 bit mode
     .adjust_env oszIn64Override
 
-    limm t2, imm
+    limm t1, imm
+    rdip t7
+    subi rsp, rsp, dsz
+    st t7, ss, [0, t0, rsp]
+    wrip t7, t1
+};
+
+def macroop CALL_NEAR_R
+{
+    # Make the default data size of calls 64 bits in 64 bit mode
+    .adjust_env oszIn64Override
+
     rdip t1
     subi rsp, rsp, dsz
     st t1, ss, [0, t0, rsp]
-    wrip t1, t2
+    wripi reg, 0
+};
+
+def macroop CALL_NEAR_M
+{
+    # Make the default data size of calls 64 bits in 64 bit mode
+    .adjust_env oszIn64Override
+
+    rdip t7
+    ld t1, ds, [scale, index, base], disp
+    subi rsp, rsp, dsz
+    st t7, ss, [0, t0, rsp]
+    wripi t1, 0
+};
+
+def macroop CALL_NEAR_P
+{
+    # Make the default data size of calls 64 bits in 64 bit mode
+    .adjust_env oszIn64Override
+
+    rdip t7
+    ld t1, ds, [0, t0, t7], disp
+    subi rsp, rsp, dsz
+    st t7, ss, [0, t0, rsp]
+    wripi t1, 0
 };
 '''
 #let {{
index 489eb9e3903e2a1244287220c0e9153bf6c4617b..158861a3dad2993e5fdffa6a66844ec07e31c2b4 100644 (file)
@@ -235,4 +235,10 @@ def macroop JMP_M
     wripi t1, 0
 };
 
+def macroop JMP_P
+{
+    rdip t7
+    ld t1, ds, [0, t0, t7], disp
+    wripi t1, 0
+};
 '''
index 585437b8c103a6600d2cf72fb0cd009e6b8748d5..c381dc4f4b57b2974b6bcc924b18f1c6f19ff1aa 100644 (file)
@@ -69,6 +69,25 @@ def macroop PUSH_R {
     subi rsp, rsp, dsz
     st reg, ss, [0, t0, rsp]
 };
+
+def macroop PUSH_M {
+    # Make the default data size of pops 64 bits in 64 bit mode
+    .adjust_env oszIn64Override
+
+    ld t1, ds, [scale, index, base], disp
+    subi rsp, rsp, dsz
+    st t1, ss, [0, t0, rsp]
+};
+
+def macroop PUSH_P {
+    # Make the default data size of pops 64 bits in 64 bit mode
+    .adjust_env oszIn64Override
+
+    rdip t7
+    ld t1, ds, [0, t0, t7], disp
+    subi rsp, rsp, dsz
+    st t1, ss, [0, t0, rsp]
+};
 '''
 #let {{
 #    class POPA(Inst):
index e3aaf0043f1cee8bb4e44f3a81b471730cf6059c..5330b1ac55f277c5a165ef622ffe0c8119144ed0 100644 (file)
 #
 # Authors: Gabe Black
 
-microcode = ""
+microcode = '''
+def macroop ROL_R_I
+{
+    rol reg, reg, imm
+};
+
+def macroop ROL_M_I
+{
+    ld t1, ds, [scale, index, base], disp
+    rol t1, t1, imm
+    st t1, ds, [scale, index, base], disp
+};
+
+def macroop ROL_P_I
+{
+    rdip t7
+    ld t1, ds, [0, t0, t7], disp
+    rol t1, t1, imm
+    st t1, ds, [0, t0, t7], disp
+};
+
+def macroop ROR_R_I
+{
+    ror reg, reg, imm
+};
+
+def macroop ROR_M_I
+{
+    ld t1, ds, [scale, index, base], disp
+    ror t1, t1, imm
+    st t1, ds, [scale, index, base], disp
+};
+
+def macroop ROR_P_I
+{
+    rdip t7
+    ld t1, ds, [0, t0, t7], disp
+    ror t1, t1, imm
+    st t1, ds, [0, t0, t7], disp
+};
+'''
 #let {{
 #    class RCL(Inst):
 #      "GenFault ${new UnimpInstFault}"
 #    class RCR(Inst):
 #      "GenFault ${new UnimpInstFault}"
-#    class ROL(Inst):
-#      "GenFault ${new UnimpInstFault}"
-#    class ROR(Inst):
-#      "GenFault ${new UnimpInstFault}"
 #}};
index b1c86a921e902dd247f416965f33c18ea18f7e25..5a04317d93cef946ee929e8aab084e56ba937664 100644 (file)
@@ -73,6 +73,46 @@ def macroop SAL_P_I
     sll t1, t1, imm
     st t1, ds, [0, t0, t7], disp
 };
+
+def macroop SHR_R_I
+{
+    srl reg, reg, imm
+};
+
+def macroop SHR_M_I
+{
+    ld t1, ds, [scale, index, base], disp
+    srl t1, t1, imm
+    st t1, ds, [scale, index, base], disp
+};
+
+def macroop SHR_P_I
+{
+    rdip t7
+    ld t1, ds, [0, t0, t7], disp
+    srl t1, t1, imm
+    st t1, ds, [0, t0, t7], disp
+};
+
+def macroop SAR_R_I
+{
+    sra reg, reg, imm
+};
+
+def macroop SAR_M_I
+{
+    ld t1, ds, [scale, index, base], disp
+    sra t1, t1, imm
+    st t1, ds, [scale, index, base], disp
+};
+
+def macroop SAR_P_I
+{
+    rdip t7
+    ld t1, ds, [0, t0, t7], disp
+    sra t1, t1, imm
+    st t1, ds, [0, t0, t7], disp
+};
 '''
 #let {{
 #    class SAL(Inst):
index d2002b4fb267e59ce52c50be65ffca97187a7504..1f4de56424a0239f7a9fd47db72807571215bbe8 100644 (file)
@@ -381,34 +381,6 @@ let {{
         setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
                 flagCode = immFlagCode, condCheck = condCode, elseCode = elseCode);
 
-    defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
-    defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
-    defineMicroRegOp('Adc', '''
-            CCFlagBits flags = ccFlagBits;
-            DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
-            ''')
-    defineMicroRegOp('Sbb', '''
-            CCFlagBits flags = ccFlagBits;
-            DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
-            ''', True)
-    defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
-    defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
-    defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
-    # defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
-    defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
-    defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
-            elseCode='DestReg=DestReg;', cc=True)
-
-    # Shift instructions
-    defineMicroRegOp('Sll', '''
-            uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
-            DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
-            ''')
-    # There are special rules for the flag for a single bit shift
-    defineMicroRegOp('Bll', '''
-            DestReg = merge(DestReg, SrcReg1 << 1, dataSize);
-            ''')
-
     # This has it's own function because Wr ops have implicit destinations
     def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
         Name = mnemonic
@@ -445,8 +417,6 @@ let {{
         setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
                 condCheck = checkCCFlagBits, elseCode = elseCode);
 
-    defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
-
     # This has it's own function because Rd ops don't always have two parameters
     def defineMicroRegOpRd(mnemonic, code):
         Name = mnemonic
@@ -462,8 +432,6 @@ let {{
 
         setUpMicroRegOp(name, Name, "X86ISA::RegOp", code);
 
-    defineMicroRegOpRd('Rdip', 'DestReg = RIP')
-
     def defineMicroRegOpImm(mnemonic, code):
         Name = mnemonic
         name = mnemonic.lower()
@@ -478,6 +446,80 @@ let {{
 
         setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
 
+    defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
+    defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
+    defineMicroRegOp('Adc', '''
+            CCFlagBits flags = ccFlagBits;
+            DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
+            ''')
+    defineMicroRegOp('Sbb', '''
+            CCFlagBits flags = ccFlagBits;
+            DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
+            ''', True)
+    defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
+    defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
+    defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
+    # defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
+    defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
+    defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
+            elseCode='DestReg=DestReg;', cc=True)
+
+    # Shift instructions
+    defineMicroRegOp('Sll', '''
+            uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+            DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
+            ''')
+    defineMicroRegOp('Srl', '''
+            uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+            // Because what happens to the bits shift -in- on a right shift
+            // is not defined in the C/C++ standard, we have to mask them out
+            // to be sure they're zero.
+            uint64_t logicalMask = mask(dataSize * 8 - shiftAmt);
+            DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) & logicalMask, dataSize);
+            ''')
+    defineMicroRegOp('Sra', '''
+            uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+            // Because what happens to the bits shift -in- on a right shift
+            // is not defined in the C/C++ standard, we have to sign extend
+            // them manually to be sure.
+            uint64_t arithMask =
+                -bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
+            DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) | arithMask, dataSize);
+            ''')
+    defineMicroRegOp('Ror', '''
+            uint8_t shiftAmt =
+                (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+            if(shiftAmt)
+            {
+                uint64_t top = SrcReg1 << (dataSize * 8 - shiftAmt);
+                uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
+                DestReg = merge(DestReg, top | bottom, dataSize);
+            }
+            else
+                DestReg = DestReg;
+            ''')
+    defineMicroRegOp('Rcr', '''
+            ''')
+    defineMicroRegOp('Rol', '''
+            uint8_t shiftAmt =
+                (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+            if(shiftAmt)
+            {
+                uint64_t top = SrcReg1 << shiftAmt;
+                uint64_t bottom =
+                    bits(SrcReg1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
+                DestReg = merge(DestReg, top | bottom, dataSize);
+            }
+            else
+                DestReg = DestReg;
+            ''')
+    defineMicroRegOp('Rcl', '''
+            ''')
+
+    defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
+
+    defineMicroRegOpRd('Rdip', 'DestReg = RIP')
+
     defineMicroRegOpImm('Sext', '''
             IntReg val = SrcReg1;
             int sign_bit = bits(val, imm8-1, imm8-1);