X86: Make instructions use pick, and implement/adjust some multiplication microops...
authorGabe Black <gblack@eecs.umich.edu>
Mon, 30 Jul 2007 20:28:05 +0000 (13:28 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 30 Jul 2007 20:28:05 +0000 (13:28 -0700)
--HG--
extra : convert_revision : 5c56f6819ee07d936b388b3d1810a3b73db84f9c

src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py
src/arch/x86/isa/microops/regop.isa

index 339e18cf8a1f5dd2ecca9d64145333ca89848539..936fa6973c4ffa01286f3870c80b7b1af5e005d2 100644 (file)
 
 microcode = '''
 
+#
+# Byte version of one operand unsigned multiply.
+#
+
+def macroop MUL_B_R
+{
+    mul1u rax, rax, reg, dataSize="2"
+};
+
+def macroop MUL_B_M
+{
+    ld t1, ds, [scale, index, base], disp
+    mul1u rax, rax, t1, dataSize="2"
+};
+
+def macroop MUL_B_P
+{
+    rdip t7
+    ld t1, ds, [scale, index, base], disp
+    mul1u rax, rax, t1, dataSize="2"
+};
+
+#
+# One operand unsigned multiply.
+#
+
+def macroop MUL_R
+{
+    muleh rdx, rax, reg
+    mulel rax, rax, reg
+};
+
+def macroop MUL_M
+{
+    ld t1, ds, [scale, index, base], disp
+    muleh rdx, rax, t1
+    mulel rax, rax, t1
+};
+
+def macroop MUL_P
+{
+    rdip t7
+    ld t1, ds, [scale, index, base], disp
+    muleh rdx, rax, t1
+    mulel rax, rax, t1
+};
+
+#
+# Byte version of one operand signed multiply.
+#
+
+def macroop IMUL_B_R
+{
+    mul1s rax, rax, reg, dataSize="2"
+};
+
+def macroop IMUL_B_M
+{
+    ld t1, ds, [scale, index, base], disp
+    mul1s rax, rax, t1, dataSize="2"
+};
+
+def macroop IMUL_B_P
+{
+    rdip t7
+    ld t1, ds, [scale, index, base], disp
+    mul1s rax, rax, t1, dataSize="2"
+};
+
+#
+# One operand signed multiply.
+#
+
+def macroop IMUL_R
+{
+    muleh rdx, rax, reg
+    mulel rax, rax, reg
+};
+
+def macroop IMUL_M
+{
+    ld t1, ds, [scale, index, base], disp
+    muleh rdx, rax, t1
+    mulel rax, rax, t1
+};
+
+def macroop IMUL_P
+{
+    rdip t7
+    ld t1, ds, [scale, index, base], disp
+    muleh rdx, rax, t1
+    mulel rax, rax, t1
+};
+
 #
 # Two operand signed multiply. These should set the CF and OF flags if the
 # result is too large for the destination register
@@ -62,33 +156,37 @@ microcode = '''
 
 def macroop IMUL_R_R
 {
-    mul1s reg, reg, regm
+    mulel reg, reg, regm
 };
 
 def macroop IMUL_R_M
 {
     ld t1, ds, [scale, index, base], disp
-    mul1s reg, reg, t1
+    mulel reg, reg, t1
 };
 
 def macroop IMUL_R_P
 {
     rdip t7
     ld t1, ds, [scale, index, base], disp
-    mul1s reg, reg, t1
+    mulel reg, reg, t1
 };
 
+#
+# Three operand signed multiply.
+#
+
 def macroop IMUL_R_R_I
 {
     limm t1, imm
-    mul1s reg, regm, t1
+    mulel reg, regm, t1
 };
 
 def macroop IMUL_R_M_I
 {
     limm t1, imm
     ld t2, ds, [scale, index, base], disp
-    mul1s reg, t2, t1
+    mulel reg, t2, t1
 };
 
 def macroop IMUL_R_P_I
@@ -96,7 +194,7 @@ def macroop IMUL_R_P_I
     rdip t7
     limm t1, imm
     ld t2, ds, [0, t0, t7]
-    mul1s reg, t2, t1
+    mulel reg, t2, t1
 };
 '''
 #let {{
index af3ee869ba11346ed5ce939cd0fd894e89db5f1a..9b7d74f50eca55ec025847c7c32d4dfed3b58f98 100644 (file)
@@ -65,6 +65,7 @@ def template MicroRegOpExecute {{
         {
             Fault fault = NoFault;
 
+            DPRINTF(X86, "The data size is %d\n", dataSize);
             %(op_decl)s;
             %(op_rd)s;
 
@@ -327,18 +328,26 @@ let {{
 
     checkCCFlagBits = "checkCondition(ccFlagBits)"
     genCCFlagBits = \
-        "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, op2);"
+        "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, src1, op2);"
     genCCFlagBitsSub = \
-        "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, ~op2, true);"
+        "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, src1, ~op2, true);"
     genCCFlagBitsLogic = '''
         //Don't have genFlags handle the OF or CF bits
         uint64_t mask = CFBit | OFBit;
-        ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, SrcReg1, op2);
+        ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, src1, op2);
         //If a logic microop wants to set these, it wants to set them to 0.
         ccFlagBits &= ~(CFBit & ext);
         ccFlagBits &= ~(OFBit & ext);
     '''
 
+    regPick = '''
+        IntReg src1 = pick(SrcReg1, 0, dataSize);
+        IntReg src2 = pick(SrcReg2, 1, dataSize);
+    '''
+    immPick = '''
+        IntReg src1 = pick(SrcReg1, 0, dataSize);
+    '''
+
 
     # This creates a python representations of a microop which are a cross
     # product of reg/immediate and flag/no flag versions.
@@ -351,8 +360,8 @@ let {{
         # of the code, one with an integer operand, and one with an immediate
         # operand.
         matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
-        regCode = matcher.sub("SrcReg2", code)
-        immCode = matcher.sub("imm8", code)
+        regCode = regPick + matcher.sub("src2", code)
+        immCode = immPick + matcher.sub("imm8", code)
 
         if not cc:
             condCode = "true"
@@ -360,7 +369,7 @@ let {{
             flagCode = ""
             condCode = checkCCFlagBits
 
-        regFlagCode = matcher.sub("SrcReg2", flagCode)
+        regFlagCode = matcher.sub("src2", flagCode)
         immFlagCode = matcher.sub("imm8", flagCode)
 
         class RegOpChild(RegOp):
@@ -374,8 +383,9 @@ let {{
         microopClasses[name] = RegOpChild
 
         setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
-        setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
-                flagCode=regFlagCode, condCheck=condCode, elseCode=elseCode);
+        setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp",
+                regCode, flagCode=regFlagCode,
+                condCheck=condCode, elseCode=elseCode);
 
         class RegOpChildImm(RegOpImm):
             mnemonic = name + 'i'
@@ -388,8 +398,9 @@ let {{
         microopClasses[name + 'i'] = RegOpChildImm
 
         setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode);
-        setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
-                flagCode=immFlagCode, condCheck=condCode, elseCode=elseCode);
+        setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm",
+                immCode, flagCode=immFlagCode,
+                condCheck=condCode, elseCode=elseCode);
 
     # This has it's own function because Wr ops have implicit destinations
     def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
@@ -400,8 +411,8 @@ let {{
         # of the code, one with an integer operand, and one with an immediate
         # operand.
         matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
-        regCode = matcher.sub("SrcReg2", code)
-        immCode = matcher.sub("imm8", code)
+        regCode = regPick + matcher.sub("src2", code)
+        immCode = immPick + matcher.sub("imm8", code)
 
         class RegOpChild(RegOp):
             mnemonic = name
@@ -445,6 +456,7 @@ let {{
     def defineMicroRegOpImm(mnemonic, code):
         Name = mnemonic
         name = mnemonic.lower()
+        code = immPick + code
 
         class RegOpChild(RegOpImm):
             def __init__(self, dest, src1, src2, dataSize="env.dataSize"):
@@ -456,35 +468,66 @@ let {{
 
         setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
 
-    defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
-    defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)',
+    defineMicroRegOp('Add', 'DestReg = merge(DestReg, src1 + op2, dataSize)')
+    defineMicroRegOp('Or', '''
+            DPRINTF(X86, "src1 = %#x\\n", src1);
+            DPRINTF(X86, "op2 = %#x\\n", op2);
+            DestReg = merge(DestReg, src1 | op2, dataSize);
+            ''',
             flagCode = genCCFlagBitsLogic)
     defineMicroRegOp('Adc', '''
             CCFlagBits flags = ccFlagBits;
-            DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
+            DestReg = merge(DestReg, src1 + op2 + flags.CF, dataSize);
             ''')
     defineMicroRegOp('Sbb', '''
             CCFlagBits flags = ccFlagBits;
-            DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
+            DestReg = merge(DestReg, src1 - op2 - flags.CF, dataSize);
             ''', flagCode = genCCFlagBitsSub)
     defineMicroRegOp('And', \
-            'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)', \
+            'DestReg = merge(DestReg, src1 & op2, dataSize)', \
             flagCode = genCCFlagBitsLogic)
     defineMicroRegOp('Sub', \
-            'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', \
+            'DestReg = merge(DestReg, src1 - op2, dataSize)', \
             flagCode = genCCFlagBitsSub)
     defineMicroRegOp('Xor', \
-            'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)', \
+            'DestReg = merge(DestReg, src1 ^ op2, dataSize)', \
             flagCode = genCCFlagBitsLogic)
-    defineMicroRegOp('Mul1s', \
-            'DestReg = merge(DestReg, DestReg * op2, dataSize)')
-    defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
+    defineMicroRegOp('Mul1s', '''
+            int signPos = (dataSize * 8) / 2 - 1;
+            IntReg srcVal1 = src1 | (-bits(src1, signPos) << signPos);
+            IntReg srcVal2 = op2 | (-bits(src1, signPos) << signPos);
+            DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
+            ''')
+    defineMicroRegOp('Mul1u', '''
+            int halfSize = (dataSize * 8) / 2;
+            IntReg srcVal1 = src1 & mask(halfSize);
+            IntReg srcVal2 = op2 & mask(halfSize);
+            DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
+            ''')
+    defineMicroRegOp('Mulel', \
+            'DestReg = merge(DestReg, src1 * op2, dataSize)')
+    defineMicroRegOp('Muleh', '''
+            int halfSize = (dataSize * 8) / 2;
+            uint64_t src1_h = src1 >> halfSize;
+            uint64_t src1_l = src1 & mask(halfSize);
+            uint64_t src2_h = op2 >> halfSize;
+            uint64_t src2_l = op2 & mask(halfSize);
+            uint64_t result =
+                ((src1_l * src2_h) >> halfSize) +
+                ((src1_h * src2_l) >> halfSize) +
+                src1_h * src2_h;
+            DestReg = merge(DestReg, result, dataSize);
+            ''')
+    #
+    # HACK HACK HACK HACK - Put src1 in here but make it inert to shut up gcc.
+    #
+    defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, src1 * 0 + op2, dataSize)',
             elseCode='DestReg=DestReg;', cc=True)
 
     # Shift instructions
     defineMicroRegOp('Sll', '''
             uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
-            DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
+            DestReg = merge(DestReg, src1 << shiftAmt, dataSize);
             ''')
     defineMicroRegOp('Srl', '''
             uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
@@ -492,7 +535,7 @@ let {{
             // 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);
+            DestReg = merge(DestReg, (src1 >> shiftAmt) & logicalMask, dataSize);
             ''')
     defineMicroRegOp('Sra', '''
             uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
@@ -501,15 +544,15 @@ let {{
             // them manually to be sure.
             uint64_t arithMask =
                 -bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
-            DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) | arithMask, dataSize);
+            DestReg = merge(DestReg, (src1 >> shiftAmt) | arithMask, dataSize);
             ''')
     defineMicroRegOp('Ror', '''
             uint8_t shiftAmt =
                 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
             if(shiftAmt)
             {
-                uint64_t top = SrcReg1 << (dataSize * 8 - shiftAmt);
-                uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
+                uint64_t top = src1 << (dataSize * 8 - shiftAmt);
+                uint64_t bottom = bits(src1, dataSize * 8, shiftAmt);
                 DestReg = merge(DestReg, top | bottom, dataSize);
             }
             else
@@ -523,8 +566,8 @@ let {{
                 CCFlagBits flags = ccFlagBits;
                 uint64_t top = flags.CF << (dataSize * 8 - shiftAmt);
                 if(shiftAmt > 1)
-                    top |= SrcReg1 << (dataSize * 8 - shiftAmt - 1);
-                uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
+                    top |= src1 << (dataSize * 8 - shiftAmt - 1);
+                uint64_t bottom = bits(src1, dataSize * 8, shiftAmt);
                 DestReg = merge(DestReg, top | bottom, dataSize);
             }
             else
@@ -535,9 +578,9 @@ let {{
                 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
             if(shiftAmt)
             {
-                uint64_t top = SrcReg1 << shiftAmt;
+                uint64_t top = src1 << shiftAmt;
                 uint64_t bottom =
-                    bits(SrcReg1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
+                    bits(src1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
                 DestReg = merge(DestReg, top | bottom, dataSize);
             }
             else
@@ -549,27 +592,27 @@ let {{
             if(shiftAmt)
             {
                 CCFlagBits flags = ccFlagBits;
-                uint64_t top = SrcReg1 << shiftAmt;
+                uint64_t top = src1 << shiftAmt;
                 uint64_t bottom = flags.CF << (shiftAmt - 1);
                 if(shiftAmt > 1)
                     bottom |=
-                        bits(SrcReg1, dataSize * 8 - 1,
-                                      dataSize * 8 - shiftAmt + 1);
+                        bits(src1, dataSize * 8 - 1,
+                                   dataSize * 8 - shiftAmt + 1);
                 DestReg = merge(DestReg, top | bottom, dataSize);
             }
             else
                 DestReg = DestReg;
             ''')
 
-    defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
+    defineMicroRegOpWr('Wrip', 'RIP = src1 + op2', elseCode="RIP = RIP;")
 
     defineMicroRegOpRd('Rdip', 'DestReg = RIP')
 
     defineMicroRegOpImm('Sext', '''
-            IntReg val = SrcReg1;
+            IntReg val = src1;
             int sign_bit = bits(val, imm8-1, imm8-1);
             val = sign_bit ? (val | ~mask(imm8)) : val;
             DestReg = merge(DestReg, val, dataSize);''')
 
-    defineMicroRegOpImm('Zext', 'DestReg = bits(SrcReg1, imm8-1, 0);')
+    defineMicroRegOpImm('Zext', 'DestReg = bits(src1, imm8-1, 0);')
 }};