diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-07-30 13:28:05 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-07-30 13:28:05 -0700 |
commit | bae96272a1630cd622f657a26d848784815c8c2b (patch) | |
tree | 21623f5dc69d979d911075bbbe319bf2e533c2b7 /src/arch/x86 | |
parent | fad96cd0fc3052e5e08d23c8cd29842e1e9c830e (diff) | |
download | gem5-bae96272a1630cd622f657a26d848784815c8c2b.tar.xz |
X86: Make instructions use pick, and implement/adjust some multiplication microops and instructions.
--HG--
extra : convert_revision : 5c56f6819ee07d936b388b3d1810a3b73db84f9c
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py | 110 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 117 |
2 files changed, 184 insertions, 43 deletions
diff --git a/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py b/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py index 339e18cf8..936fa6973 100644 --- a/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py +++ b/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py @@ -56,39 +56,137 @@ 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 # 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 {{ diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index af3ee869b..9b7d74f50 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -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);') }}; |