From 1af50a9e8bfc9ad65231e9a233e0f873fcb9e433 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Jul 2007 13:50:10 -0700 Subject: X86: Make arithmetic instructions set the appropriate flags. --HG-- extra : convert_revision : 3bdef3876c7b86bc93365edee876b74a201d625f --- .../x86/isa/insts/arithmetic/add_and_subtract.py | 64 +++++++++++----------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py index 7e5578a3c..de4996f54 100644 --- a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py +++ b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py @@ -56,20 +56,20 @@ microcode = ''' def macroop ADD_R_R { - add reg, reg, regm + add reg, reg, regm, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop ADD_R_I { limm t1, imm - add reg, reg, t1 + add reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop ADD_M_I { limm t2, imm ld t1, ds, [scale, index, base], disp - add t1, t1, t2 + add t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -78,14 +78,14 @@ def macroop ADD_P_I rdip t7 limm t2, imm ld t1, ds, [0, t0, t7], disp - add t1, t1, t2 + add t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [0, t0, t7], disp }; def macroop ADD_M_R { ld t1, ds, [scale, index, base], disp - add t1, t1, reg + add t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -93,52 +93,52 @@ def macroop ADD_P_R { rdip t7 ld t1, ds, [0, t0, t7], disp - add t1, t1, reg + add t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [0, t0, t7], disp }; def macroop ADD_R_M { ld t1, ds, [scale, index, base], disp - add reg, reg, t1 + add reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop ADD_R_P { rdip t7 ld t1, ds, [0, t0, t7], disp - add reg, reg, t1 + add reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop SUB_R_R { - sub reg, reg, regm + sub reg, reg, regm, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop SUB_R_I { limm t1, imm - sub reg, reg, t1 + sub reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop SUB_R_M { ld t1, ds, [scale, index, base], disp - sub reg, reg, t1 + sub reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop SUB_R_P { rdip t7 ld t1, ds, [0, t0, t7], disp - sub reg, reg, t1 + sub reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop SUB_M_I { limm t2, imm ld t1, ds, [scale, index, base], disp - sub t1, t1, t2 + sub t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -147,14 +147,14 @@ def macroop SUB_P_I rdip t7 limm t2, imm ld t1, ds, [0, t0, t7], disp - sub t1, t1, t2 + sub t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [0, t0, t7], disp }; def macroop SUB_M_R { ld t1, ds, [scale, index, base], disp - sub t1, t1, reg + sub t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -162,26 +162,26 @@ def macroop SUB_P_R { rdip t7 ld t1, ds, [0, t0, t7], disp - sub t1, t1, reg + sub t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [0, t0, t7], disp }; def macroop ADC_R_R { - adc reg, reg, regm + adc reg, reg, regm, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop ADC_R_I { limm t1, imm - adc reg, reg, t1 + adc reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop ADC_M_I { limm t2, imm ld t1, ds, [scale, index, base], disp - adc t1, t1, t2 + adc t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -190,14 +190,14 @@ def macroop ADC_P_I rdip t7 limm t2, imm ld t1, ds, [0, t0, t7], disp - adc t1, t1, t2 + adc t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [0, t0, t7], disp }; def macroop ADC_M_R { ld t1, ds, [scale, index, base], disp - adc t1, t1, reg + adc t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -205,52 +205,52 @@ def macroop ADC_P_R { rdip t7 ld t1, ds, [0, t0, t7], disp - adc t1, t1, reg + adc t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [0, t0, t7], disp }; def macroop ADC_R_M { ld t1, ds, [scale, index, base], disp - adc reg, reg, t1 + adc reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop ADC_R_P { rdip t7 ld t1, ds, [0, t0, t7], disp - adc reg, reg, t1 + adc reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop SBB_R_R { - sbb reg, reg, regm + sbb reg, reg, regm, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop SBB_R_I { limm t1, imm - sbb reg, reg, t1 + sbb reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop SBB_R_M { ld t1, ds, [scale, index, base], disp - sbb reg, reg, t1 + sbb reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop SBB_R_P { rdip t7 ld t1, ds, [0, t0, t7], disp - sbb reg, reg, t1 + sbb reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF) }; def macroop SBB_M_I { limm t2, imm ld t1, ds, [scale, index, base], disp - sbb t1, t1, t2 + sbb t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -259,14 +259,14 @@ def macroop SBB_P_I rdip t7 limm t2, imm ld t1, ds, [0, t0, t7], disp - sbb t1, t1, t2 + sbb t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [0, t0, t7], disp }; def macroop SBB_M_R { ld t1, ds, [scale, index, base], disp - sbb t1, t1, reg + sbb t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -274,7 +274,7 @@ def macroop SBB_P_R { rdip t7 ld t1, ds, [0, t0, t7], disp - sbb t1, t1, reg + sbb t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, ds, [0, t0, t7], disp }; -- cgit v1.2.3 From 7309d5ee45a7f6e71693c4f2582468eb591fc16a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Jul 2007 13:51:40 -0700 Subject: X86: Make logic instructions flag setting work. The instructions now ask for the appropriate flags to be set, and the microops do the "right thing" with the CF and OF flags, namely zero them. --HG-- extra : convert_revision : 85138a832f44c879bf8a11bd3a35b58be6272ef3 --- src/arch/x86/isa/insts/logical.py | 48 +++++++++++++++--------------- src/arch/x86/isa/microops/regop.isa | 59 ++++++++++++++++++++++++------------- 2 files changed, 62 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/arch/x86/isa/insts/logical.py b/src/arch/x86/isa/insts/logical.py index bbc15f8fa..81a4730de 100644 --- a/src/arch/x86/isa/insts/logical.py +++ b/src/arch/x86/isa/insts/logical.py @@ -56,14 +56,14 @@ microcode = ''' def macroop OR_R_R { - or reg, reg, regm + or reg, reg, regm, flags=(OF,SF,ZF,PF,CF) }; def macroop OR_M_I { limm t2, imm ld t1, ds, [scale, index, base], disp - or t1, t1, t2 + or t1, t1, t2, flags=(OF,SF,ZF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -72,14 +72,14 @@ def macroop OR_P_I limm t2, imm rdip t7 ld t1, ds, [0, t0, t7], disp - or t1, t1, t2 + or t1, t1, t2, flags=(OF,SF,ZF,PF,CF) st t1, ds, [0, t0, t7], disp }; def macroop OR_M_R { ld t1, ds, [scale, index, base], disp - or t1, t1, reg + or t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -87,45 +87,45 @@ def macroop OR_P_R { rdip t7 ld t1, ds, [0, t0, t7], disp - or t1, t1, reg + or t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, ds, [0, t0, t7], disp }; def macroop OR_R_M { ld t1, ds, [scale, index, base], disp - or reg, reg, t1 + or reg, reg, t1, flags=(OF,SF,ZF,PF,CF) }; def macroop OR_R_P { rdip t7 ld t1, ds, [0, t0, t7], disp - or reg, reg, t1 + or reg, reg, t1, flags=(OF,SF,ZF,PF,CF) }; def macroop OR_R_I { limm t1, imm - or reg, reg, t1 + or reg, reg, t1, flags=(OF,SF,ZF,PF,CF) }; def macroop XOR_R_R { - xor reg, reg, regm + xor reg, reg, regm, flags=(OF,SF,ZF,PF,CF) }; def macroop XOR_R_I { limm t1, imm - xor reg, reg, t1 + xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF) }; def macroop XOR_M_I { limm t2, imm ld t1, ds, [scale, index, base], disp - xor t1, t1, t2 + xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -134,14 +134,14 @@ def macroop XOR_P_I limm t2, imm rdip t7 ld t1, ds, [scale, index, base], disp - xor t1, t1, t2 + xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF) st t1, ds, [scale, index, base], disp }; def macroop XOR_M_R { ld t1, ds, [scale, index, base], disp - xor t1, t1, reg + xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -149,52 +149,52 @@ def macroop XOR_P_R { rdip t7 ld t1, ds, [scale, index, base], disp - xor t1, t1, reg + xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, ds, [scale, index, base], disp }; def macroop XOR_R_M { ld t1, ds, [scale, index, base], disp - xor reg, reg, t1 + xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF) }; def macroop XOR_R_P { rdip t7 ld t1, ds, [scale, index, base], disp - xor reg, reg, t1 + xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF) }; def macroop AND_R_R { - and reg, reg, regm + and reg, reg, regm, flags=(OF,SF,ZF,PF,CF) }; def macroop AND_R_M { ld t1, ds, [scale, index, base], disp - and reg, reg, t1 + and reg, reg, t1, flags=(OF,SF,ZF,PF,CF) }; def macroop AND_R_P { rdip t7 ld t1, ds, [scale, index, base], disp - and reg, reg, t1 + and reg, reg, t1, flags=(OF,SF,ZF,PF,CF) }; def macroop AND_R_I { limm t1, imm - and reg, reg, t1 + and reg, reg, t1, flags=(OF,SF,ZF,PF,CF) }; def macroop AND_M_I { ld t2, ds, [scale, index, base], disp limm t1, imm - and t2, t2, t1 + and t2, t2, t1, flags=(OF,SF,ZF,PF,CF) st t2, ds, [scale, index, base], disp }; @@ -203,14 +203,14 @@ def macroop AND_P_I rdip t7 ld t2, ds, [scale, index, base], disp limm t1, imm - and t2, t2, t1 + and t2, t2, t1, flags=(OF,SF,ZF,PF,CF) st t2, ds, [scale, index, base], disp }; def macroop AND_M_R { ld t1, ds, [scale, index, base], disp - and t1, t1, reg + and t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, ds, [scale, index, base], disp }; @@ -218,7 +218,7 @@ def macroop AND_P_R { rdip t7 ld t1, ds, [scale, index, base], disp - and t1, t1, reg + and t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, ds, [scale, index, base], disp }; diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index bb34df7df..af3ee869b 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -326,12 +326,24 @@ let {{ checkCCFlagBits = "checkCondition(ccFlagBits)" - genCCFlagBits = "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, %s);" + genCCFlagBits = \ + "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, op2);" + genCCFlagBitsSub = \ + "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, ~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); + //If a logic microop wants to set these, it wants to set them to 0. + ccFlagBits &= ~(CFBit & ext); + ccFlagBits &= ~(OFBit & ext); + ''' # This creates a python representations of a microop which are a cross # product of reg/immediate and flag/no flag versions. - def defineMicroRegOp(mnemonic, code, subtract = False, cc=False, elseCode=";"): + def defineMicroRegOp(mnemonic, code, flagCode=genCCFlagBits, \ + cc=False, elseCode=";"): Name = mnemonic name = mnemonic.lower() @@ -342,13 +354,7 @@ let {{ regCode = matcher.sub("SrcReg2", code) immCode = matcher.sub("imm8", code) - if subtract: - secondSrc = "~op2, true" - else: - secondSrc = "op2" - if not cc: - flagCode = genCCFlagBits % secondSrc condCode = "true" else: flagCode = "" @@ -360,26 +366,30 @@ let {{ class RegOpChild(RegOp): mnemonic = name className = Name - def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"): - super(RegOpChild, self).__init__(dest, src1, src2, flags, dataSize) + def __init__(self, dest, src1, src2, \ + flags=None, dataSize="env.dataSize"): + super(RegOpChild, self).__init__(dest, src1, src2, \ + flags, dataSize) microopClasses[name] = RegOpChild setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode); setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, - flagCode = regFlagCode, condCheck = condCode, elseCode = elseCode); + flagCode=regFlagCode, condCheck=condCode, elseCode=elseCode); class RegOpChildImm(RegOpImm): mnemonic = name + 'i' className = Name + 'Imm' - def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"): - super(RegOpChildImm, self).__init__(dest, src1, src2, flags, dataSize) + def __init__(self, dest, src1, src2, \ + flags=None, dataSize="env.dataSize"): + super(RegOpChildImm, self).__init__(dest, src1, src2, \ + flags, dataSize) 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); + flagCode=immFlagCode, condCheck=condCode, elseCode=elseCode); # This has it's own function because Wr ops have implicit destinations def defineMicroRegOpWr(mnemonic, code, elseCode=";"): @@ -447,7 +457,8 @@ let {{ setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code); defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') - defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)') + defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)', + flagCode = genCCFlagBitsLogic) defineMicroRegOp('Adc', ''' CCFlagBits flags = ccFlagBits; DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize); @@ -455,12 +466,18 @@ let {{ 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)') + ''', flagCode = genCCFlagBitsSub) + defineMicroRegOp('And', \ + 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)', \ + flagCode = genCCFlagBitsLogic) + defineMicroRegOp('Sub', \ + 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', \ + flagCode = genCCFlagBitsSub) + defineMicroRegOp('Xor', \ + 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)', \ + flagCode = genCCFlagBitsLogic) + defineMicroRegOp('Mul1s', \ + 'DestReg = merge(DestReg, DestReg * op2, dataSize)') defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', elseCode='DestReg=DestReg;', cc=True) -- cgit v1.2.3 From 24ac08daa4ff47eed2efeeca84d0d6fa2628eee3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:13:11 -0700 Subject: Fix problem with tracer not being initialized. --HG-- extra : convert_revision : 09610ad84afa605db2d0eab9945eb9809f297182 --- src/cpu/o3/alpha/cpu_builder.cc | 2 ++ src/cpu/o3/mips/cpu_builder.cc | 2 ++ src/cpu/o3/sparc/cpu_builder.cc | 2 ++ 3 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/cpu/o3/alpha/cpu_builder.cc b/src/cpu/o3/alpha/cpu_builder.cc index 58ee52a39..4db217abf 100644 --- a/src/cpu/o3/alpha/cpu_builder.cc +++ b/src/cpu/o3/alpha/cpu_builder.cc @@ -70,6 +70,8 @@ DerivO3CPUParams::create() params->clock = clock; params->phase = phase; + params->tracer = tracer; + params->name = name; params->numberOfThreads = actual_num_threads; params->cpu_id = cpu_id; diff --git a/src/cpu/o3/mips/cpu_builder.cc b/src/cpu/o3/mips/cpu_builder.cc index 6a30ff099..4690b9804 100644 --- a/src/cpu/o3/mips/cpu_builder.cc +++ b/src/cpu/o3/mips/cpu_builder.cc @@ -66,6 +66,8 @@ DerivO3CPUParams::create() params->clock = clock; params->phase = phase; + params->tracer = tracer; + params->name = name; params->numberOfThreads = actual_num_threads; params->cpu_id = cpu_id; diff --git a/src/cpu/o3/sparc/cpu_builder.cc b/src/cpu/o3/sparc/cpu_builder.cc index 35d9e2895..49f0f455d 100644 --- a/src/cpu/o3/sparc/cpu_builder.cc +++ b/src/cpu/o3/sparc/cpu_builder.cc @@ -71,6 +71,8 @@ DerivO3CPUParams::create() params->clock = clock; params->phase = phase; + params->tracer = tracer; + params->name = name; params->numberOfThreads = actual_num_threads; params->cpu_id = cpu_id; -- cgit v1.2.3 From e70ffb0117bc35ab346970c907a3b557fa816663 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:17:34 -0700 Subject: X86: Add a bitfield to indicate whether or not an REX prefix was present. --HG-- extra : convert_revision : 9c4802f6c6e4eaab36aac900e2c7576682cb0f33 --- src/arch/x86/isa/bitfields.isa | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/arch/x86/isa/bitfields.isa b/src/arch/x86/isa/bitfields.isa index 43fee5fef..fb082f683 100644 --- a/src/arch/x86/isa/bitfields.isa +++ b/src/arch/x86/isa/bitfields.isa @@ -60,6 +60,7 @@ //REX prefix def bitfield REX rex; +def bitfield REX_PRESENT rex.present; def bitfield REX_W rex.w; def bitfield REX_R rex.r; def bitfield REX_X rex.x; -- cgit v1.2.3 From 4b3a20cdeca2e72606c435ee59abc936cfcb6db2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:19:11 -0700 Subject: X86: Implement LEAVE --HG-- extra : convert_revision : c642d5018ece82c644e1cfa389b2d3dbd6ab5ffd --- src/arch/x86/isa/insts/data_transfer/stack_operations.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/arch/x86/isa/insts/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/data_transfer/stack_operations.py index 1c13b44b4..082e24485 100644 --- a/src/arch/x86/isa/insts/data_transfer/stack_operations.py +++ b/src/arch/x86/isa/insts/data_transfer/stack_operations.py @@ -141,6 +141,15 @@ def macroop POPA { ld rax, ss, [0, t0, rsp], "7 * env.dataSize" addi rsp, rsp, "8 * env.dataSize" }; + +def macroop LEAVE { + # Make the default data size of pops 64 bits in 64 bit mode + .adjust_env oszIn64Override + + mov rsp, rsp, rbp + ld rbp, ss, [0, t0, rsp] + addi rsp, rsp, dsz +}; ''' #let {{ # class ENTER(Inst): -- cgit v1.2.3 From 9b5421dcbabb3e085edca359d8ce29978594dd98 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:20:08 -0700 Subject: X86: Missed a file for adding a bit to indicate that an REX prefix was present. --HG-- extra : convert_revision : f1bbd5165a7415d0daf27660575d30c41510f531 --- src/arch/x86/types.hh | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh index a509ff57a..f8a5dbe34 100644 --- a/src/arch/x86/types.hh +++ b/src/arch/x86/types.hh @@ -110,6 +110,9 @@ namespace X86ISA EndBitUnion(Sib) BitUnion8(Rex) + //This bit doesn't mean anything according to the ISA, but in + //this implementation, it being set means an REX prefix was present. + Bitfield<6> present; Bitfield<3> w; Bitfield<2> r; Bitfield<1> x; -- cgit v1.2.3 From d8beeff324f0d47927716e0081fe4a72c56601f7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:23:33 -0700 Subject: X86: Make disassembly use the final register index. Add bits to indicate whether or not register indexes should be "folded". --HG-- extra : convert_revision : 4b46e71ca91e480f6e1662b7f37b75240d6598e9 --- src/arch/x86/insts/microldstop.cc | 6 +++--- src/arch/x86/insts/microldstop.hh | 7 ++++++- src/arch/x86/insts/microregop.cc | 10 +++++----- src/arch/x86/insts/microregop.hh | 2 ++ src/arch/x86/isa/microops/limmop.isa | 4 +++- 5 files changed, 19 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/arch/x86/insts/microldstop.cc b/src/arch/x86/insts/microldstop.cc index 8a52ad932..9628256e4 100644 --- a/src/arch/x86/insts/microldstop.cc +++ b/src/arch/x86/insts/microldstop.cc @@ -66,13 +66,13 @@ namespace X86ISA std::stringstream response; printMnemonic(response, instMnem, mnemonic); - printReg(response, data, dataSize); + printDestReg(response, 0, dataSize); response << ", "; printSegment(response, segment); ccprintf(response, ":[%d*", scale); - printReg(response, index, addressSize); + printSrcReg(response, 0, addressSize); response << " + "; - printReg(response, base, addressSize); + printSrcReg(response, 1, addressSize); ccprintf(response, " + %#x]", disp); return response.str(); } diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh index ae03d176e..8fef14121 100644 --- a/src/arch/x86/insts/microldstop.hh +++ b/src/arch/x86/insts/microldstop.hh @@ -76,6 +76,7 @@ namespace X86ISA const RegIndex data; const uint8_t dataSize; const uint8_t addressSize; + RegIndex foldOBit, foldABit; //Constructor LdStOp(ExtMachInst _machInst, @@ -92,7 +93,11 @@ namespace X86ISA disp(_disp), segment(_segment), data(_data), dataSize(_dataSize), addressSize(_addressSize) - {} + { + foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; + foldABit = + (addressSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; + } std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc index 976b04688..e67a82d4f 100644 --- a/src/arch/x86/insts/microregop.cc +++ b/src/arch/x86/insts/microregop.cc @@ -173,11 +173,11 @@ namespace X86ISA std::stringstream response; printMnemonic(response, instMnem, mnemonic); - printReg(response, dest, dataSize); + printDestReg(response, 0, dataSize); response << ", "; - printReg(response, src1, dataSize); + printSrcReg(response, 0, dataSize); response << ", "; - printReg(response, src2, dataSize); + printSrcReg(response, 1, dataSize); return response.str(); } @@ -187,9 +187,9 @@ namespace X86ISA std::stringstream response; printMnemonic(response, instMnem, mnemonic); - printReg(response, dest, dataSize); + printDestReg(response, 0, dataSize); response << ", "; - printReg(response, src1, dataSize); + printSrcReg(response, 0, dataSize); ccprintf(response, ", %#x", imm8); return response.str(); } diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh index f411c0775..f465ac651 100644 --- a/src/arch/x86/insts/microregop.hh +++ b/src/arch/x86/insts/microregop.hh @@ -113,6 +113,7 @@ namespace X86ISA const RegIndex dest; const uint8_t dataSize; const uint16_t ext; + RegIndex foldOBit; // Constructor RegOpBase(ExtMachInst _machInst, @@ -128,6 +129,7 @@ namespace X86ISA src1(_src1), dest(_dest), dataSize(_dataSize), ext(_ext) { + foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; } //Figure out what the condition code flags should be. diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa index ec68c36dc..c357c1d6c 100644 --- a/src/arch/x86/isa/microops/limmop.isa +++ b/src/arch/x86/isa/microops/limmop.isa @@ -78,6 +78,7 @@ def template MicroLimmOpDeclare {{ const RegIndex dest; const uint64_t imm; const uint8_t dataSize; + RegIndex foldOBit; void buildMe(); std::string generateDisassembly(Addr pc, @@ -104,7 +105,7 @@ def template MicroLimmOpDisassembly {{ std::stringstream response; printMnemonic(response, instMnem, mnemonic); - printReg(response, dest, dataSize); + printDestReg(response, 0, dataSize); response << ", "; ccprintf(response, "%#x", imm); return response.str(); @@ -115,6 +116,7 @@ def template MicroLimmOpConstructor {{ inline void %(class_name)s::buildMe() { + foldOBit = (dataSize == 1 && !machInst.rex.present) ? 1 << 6 : 0; %(constructor)s; } -- cgit v1.2.3 From da84aa95a99ef84ff10b7ce53156825e73d0b8e5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:25:00 -0700 Subject: Make the register indices use the appropriate "fold" bit. --HG-- extra : convert_revision : 89e15e2ef1f709f2c09238b78f94505ce8ef146d --- src/arch/x86/isa/operands.isa | 14 +++++++------- src/arch/x86/regfile.cc | 9 +++++++-- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 406c74a1f..127e1b98a 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -96,13 +96,13 @@ def operand_types {{ }}; def operands {{ - 'DestReg': ('IntReg', 'uqw', 'dest', 'IsInteger', 1), - 'SrcReg1': ('IntReg', 'uqw', 'src1', 'IsInteger', 2), - 'SrcReg2': ('IntReg', 'uqw', 'src2', 'IsInteger', 3), - 'Base': ('IntReg', 'uqw', 'base', 'IsInteger', 4), - 'Index': ('IntReg', 'uqw', 'index', 'IsInteger', 5), - 'Data': ('IntReg', 'uqw', 'data', 'IsInteger', 6), - 'rax': ('IntReg', 'uqw', 'INTREG_RAX', 'IsInteger', 7), + 'SrcReg1': ('IntReg', 'uqw', '(((src1 & 0xC) == 4 ? foldOBit : 0) | src1)', 'IsInteger', 1), + 'SrcReg2': ('IntReg', 'uqw', '(((src2 & 0xC) == 4 ? foldOBit : 0) | src2)', 'IsInteger', 2), + 'Base': ('IntReg', 'uqw', '(((base & 0xC) == 4 ? foldABit : 0) | base)', 'IsInteger', 3), + 'Index': ('IntReg', 'uqw', '(((index & 0xC) == 4 ? foldABit : 0) | index)', 'IsInteger', 4), + 'DestReg': ('IntReg', 'uqw', '(((dest & 0xC) == 4 ? foldOBit : 0) | dest)', 'IsInteger', 5), + 'Data': ('IntReg', 'uqw', '(((data & 0xC) == 4 ? foldOBit : 0) | data)', 'IsInteger', 6), + 'rax': ('IntReg', 'uqw', '(INTREG_RAX)', 'IsInteger', 7), 'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 10), 'ccFlagBits': ('IntReg', 'uqw', 'NUM_INTREGS + NumMicroIntRegs', None, 20), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100) diff --git a/src/arch/x86/regfile.cc b/src/arch/x86/regfile.cc index f54f531e2..96283cada 100644 --- a/src/arch/x86/regfile.cc +++ b/src/arch/x86/regfile.cc @@ -86,6 +86,7 @@ */ #include "arch/x86/regfile.hh" +#include "base/trace.hh" #include "sim/serialize.hh" #include "cpu/thread_context.hh" @@ -209,8 +210,12 @@ void RegFile::setIntReg(int intReg, const IntReg &val) int X86ISA::flattenIntIndex(ThreadContext * tc, int reg) { - //For right now, don't do any flattening - return reg; + //If we need to fold over the index to match byte semantics, do that. + //Otherwise, just strip off any extra bits and pass it through. + if (reg & (1 << 6)) + return (reg & ~(1 << 6) - 0x4); + else + return (reg & ~(1 << 6)); } void RegFile::serialize(std::ostream &os) -- cgit v1.2.3 From 31a862b8f1ed35c1fe80b0529ee5bafdc20e3665 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:25:38 -0700 Subject: X86: missed a file which adds a "fold" bit. --HG-- extra : convert_revision : 2c8eea425221d069a9bb888c8f18839843061899 --- src/arch/x86/isa/formats/syscall.isa | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/arch/x86/isa/formats/syscall.isa b/src/arch/x86/isa/formats/syscall.isa index 8b860dba4..2f88c8d23 100644 --- a/src/arch/x86/isa/formats/syscall.isa +++ b/src/arch/x86/isa/formats/syscall.isa @@ -65,6 +65,7 @@ output header {{ class SyscallInst : public X86ISA::X86StaticInst { public: + static const RegIndex foldOBit = 0; /// Constructor SyscallInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass) : -- cgit v1.2.3 From 0d31a41304c56b68d3544a520a1c0f1e8d779bfe Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:26:14 -0700 Subject: X86: Make register names in disassembly reflect high bytes. --HG-- extra : convert_revision : e2891581e5504de0a2c8e5932fd22425cafd4fc7 --- src/arch/x86/insts/static_inst.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc index 9b2f81e49..948a74bc1 100644 --- a/src/arch/x86/insts/static_inst.cc +++ b/src/arch/x86/insts/static_inst.cc @@ -117,15 +117,27 @@ namespace X86ISA { assert(size == 1 || size == 2 || size == 4 || size == 8); static const char * abcdFormats[9] = - {"", "%sl", "%sx", "", "e%sx", "", "", "", "r%sx"}; + {"", "%s", "%sx", "", "e%sx", "", "", "", "r%sx"}; static const char * piFormats[9] = - {"", "%sl", "%s", "", "e%s", "", "", "", "r%s"}; + {"", "%s", "%s", "", "e%s", "", "", "", "r%s"}; static const char * longFormats[9] = {"", "r%sb", "r%sw", "", "r%sd", "", "", "", "r%s"}; static const char * microFormats[9] = {"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"}; if (reg < FP_Base_DepTag) { + char * suffix = ""; + bool fold = reg & (1 << 6); + reg &= ~(1 << 6); + + if(fold) + { + suffix = "h"; + reg -= 4; + } + else if(reg < 8 && size == 1) + suffix = "l"; + switch (reg) { case INTREG_RAX: ccprintf(os, abcdFormats[size], "a"); @@ -178,6 +190,7 @@ namespace X86ISA default: ccprintf(os, microFormats[size], reg - NUM_INTREGS); } + ccprintf(os, suffix); } else if (reg < Ctrl_Base_DepTag) { ccprintf(os, "%%f%d", reg - FP_Base_DepTag); } else { -- cgit v1.2.3 From fad96cd0fc3052e5e08d23c8cd29842e1e9c830e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:26:48 -0700 Subject: X86: Make merge and pick work with high bytes. Fix a sizing issue in pick. --HG-- extra : convert_revision : 4ddc2ca8c23bb7e90a646329ebf27a013ac5e3d6 --- src/arch/x86/insts/static_inst.hh | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh index f42e6693d..22139fc77 100644 --- a/src/arch/x86/insts/static_inst.hh +++ b/src/arch/x86/insts/static_inst.hh @@ -92,9 +92,12 @@ namespace X86ISA inline uint64_t merge(uint64_t into, uint64_t val, int size) const { - X86IntReg reg; - reg = into; - //FIXME This needs to be handle high bytes as well + X86IntReg reg = into; + if(_destRegIdx[0] & (1 << 6)) + { + reg.H = val; + return reg; + } switch(size) { case 1: @@ -117,18 +120,20 @@ namespace X86ISA return reg; } - inline uint64_t pick(uint64_t from, int size) + inline uint64_t pick(uint64_t from, int idx, int size) const { - X86IntReg reg; - reg = from; + X86IntReg reg = from; + DPRINTF(X86, "Picking with size %d\n", size); + if(_srcRegIdx[idx] & (1 << 6)) + return reg.H; switch(size) { case 1: return reg.L; case 2: - return reg.E; - case 4: return reg.X; + case 4: + return reg.E; case 8: return reg.R; default: -- cgit v1.2.3 From bae96272a1630cd622f657a26d848784815c8c2b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:28:05 -0700 Subject: X86: Make instructions use pick, and implement/adjust some multiplication microops and instructions. --HG-- extra : convert_revision : 5c56f6819ee07d936b388b3d1810a3b73db84f9c --- .../isa/insts/arithmetic/multiply_and_divide.py | 110 +++++++++++++++++-- src/arch/x86/isa/microops/regop.isa | 117 ++++++++++++++------- 2 files changed, 184 insertions(+), 43 deletions(-) (limited to 'src') 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 @@ -55,6 +55,100 @@ 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 {{ 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\\.\\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\\.\\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);') }}; -- cgit v1.2.3 From dbc979b9e283e39562c425f97d15802bdb958452 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:28:31 -0700 Subject: X86: Force jumps to use 64 bit operand size. --HG-- extra : convert_revision : 1c3685e7f4d07d5b4ded6c78b794964f51a358a9 --- src/arch/x86/isa/insts/control_transfer/jump.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py index 158861a3d..0df84cbe8 100644 --- a/src/arch/x86/isa/insts/control_transfer/jump.py +++ b/src/arch/x86/isa/insts/control_transfer/jump.py @@ -226,17 +226,26 @@ def macroop JMP_I def macroop JMP_R { + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + wripi reg, 0 }; def macroop JMP_M { + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + ld t1, ds, [scale, index, base], disp wripi t1, 0 }; def macroop JMP_P { + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + rdip t7 ld t1, ds, [0, t0, t7], disp wripi t1, 0 -- cgit v1.2.3 From 18be07289f8cfc733097c2f759676fbcacd7db1e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:29:33 -0700 Subject: X86: Implement a stub CPUID function which is hardcode to return certain values. --HG-- extra : convert_revision : 4085e04fd13e834646106faa55726d07d9631f42 --- src/arch/x86/isa/insts/processor_information.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/x86/isa/insts/processor_information.py b/src/arch/x86/isa/insts/processor_information.py index b9c8a407e..f7ef4db98 100644 --- a/src/arch/x86/isa/insts/processor_information.py +++ b/src/arch/x86/isa/insts/processor_information.py @@ -53,7 +53,20 @@ # # Authors: Gabe Black -microcode = "" +microcode = ''' +def macroop CPUID_R { + # + # For now, the CPUID function number will be hard wired to 0x8000_0000. + # Getting it to work more robustly will likely require microcode branching + # which probably doesn't work at the moment. + # + + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 +}; +''' #let {{ # class CPUID(Inst): # "GenFault ${new UnimpInstFault}" -- cgit v1.2.3 From 9e2b1f863058ca5ca921bf0ae65cbac8491dfed1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:29:56 -0700 Subject: X86: Make sure FP_Base_DepTag is big enough to avoid trouble. --HG-- extra : convert_revision : 7e0a83d5deb7fc9aaa69b7d024ea6ae6890df133 --- src/arch/x86/isa_traits.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/x86/isa_traits.hh b/src/arch/x86/isa_traits.hh index 63bcfead9..466422ced 100644 --- a/src/arch/x86/isa_traits.hh +++ b/src/arch/x86/isa_traits.hh @@ -82,7 +82,7 @@ namespace X86ISA // These enumerate all the registers for dependence tracking. enum DependenceTags { //There are 16 microcode registers at the moment - FP_Base_DepTag = 32, + FP_Base_DepTag = 1 << 7, Ctrl_Base_DepTag = FP_Base_DepTag + //mmx/x87 registers -- cgit v1.2.3 From ab8ba813c9decf7fa29b6dd699195e53f7c109ad Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:30:41 -0700 Subject: X86: Turn on some system calls, and make the kernel version match my development machine. --HG-- extra : convert_revision : 2f1969a45aa82708dc4cddef09c01306f76f0a81 --- src/arch/x86/linux/syscalls.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 5c756ec7f..06509c974 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -71,7 +71,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); - strcpy(name->release, "2.6.12"); + strcpy(name->release, "2.6.16.19"); strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); strcpy(name->machine, "x86_64"); @@ -81,12 +81,12 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } SyscallDesc X86LinuxProcess::syscallDescs[] = { - /* 0 */ SyscallDesc("read", unimplementedFunc), + /* 0 */ SyscallDesc("read", readFunc), /* 1 */ SyscallDesc("write", unimplementedFunc), /* 2 */ SyscallDesc("open", openFunc), - /* 3 */ SyscallDesc("close", unimplementedFunc), + /* 3 */ SyscallDesc("close", closeFunc), /* 4 */ SyscallDesc("stat", unimplementedFunc), - /* 5 */ SyscallDesc("fstat", unimplementedFunc), + /* 5 */ SyscallDesc("fstat", fstat64Func), /* 6 */ SyscallDesc("lstat", unimplementedFunc), /* 7 */ SyscallDesc("poll", unimplementedFunc), /* 8 */ SyscallDesc("lseek", unimplementedFunc), -- cgit v1.2.3 From a1b193f02645e95e9daa77b18da526cf166eaee5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:31:27 -0700 Subject: X86: Hook in the new instructions. --HG-- extra : convert_revision : c4233001b35b52161083482841593ec28da6ff7d --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 10 +++++----- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 3b51f9d73..3253c9fec 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -395,7 +395,7 @@ } 0x19: decode OPCODE_OP_BOTTOM3 { 0x0: enter_Iw_Ib(); - 0x1: leave(); + 0x1: Inst::LEAVE(); 0x2: ret_far_Iw(); 0x3: ret_far(); 0x4: int3(); @@ -519,8 +519,8 @@ 0x1: Inst::TEST(Eb,Iz); 0x2: Inst::NOT(Eb); 0x3: Inst::NEG(Eb); - 0x4: mul_Eb(); - 0x5: imul_Eb(); + 0x4: Inst::MUL_B(Eb); + 0x5: Inst::IMUL_B(Eb); 0x6: div_Eb(); 0x7: idiv_Eb(); } @@ -530,8 +530,8 @@ 0x1: Inst::TEST(Ev,Iz); 0x2: Inst::NOT(Ev); 0x3: Inst::NEG(Ev); - 0x4: mul_Ev(); - 0x5: imul_Ev(); + 0x4: Inst::MUL(Ev); + 0x5: Inst::IMUL(Ev); 0x6: div_Ev(); 0x7: idiv_Ev(); } diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index da4c82afa..a8c4e7062 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -311,7 +311,7 @@ 0x14: decode OPCODE_OP_BOTTOM3 { 0x0: push_fs(); 0x1: pop_fs(); - 0x2: cpuid(); + 0x2: Inst::CPUID(rAd); 0x3: bt_Ev_Gv(); 0x4: shld_Ev_Gv_Ib(); 0x5: shld_Ev_Gv_rCl(); -- cgit v1.2.3 From 9536120845bcd3b807e942d42364952ce0d3d090 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 13:31:59 -0700 Subject: X86: Fix up the stat structure. This probably still isn't right. --HG-- extra : convert_revision : 2e2a22cdf3abe648c9e1309b9070cfd10fc4a8b8 --- src/arch/x86/linux/linux.hh | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index c1bb67260..d6dd81ab9 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -65,23 +65,25 @@ class X86Linux64 : public Linux public: typedef struct { - uint32_t st_dev; - char __pad1[4]; + uint64_t st_dev; uint64_t st_ino; + uint64_t st_nlink; uint32_t st_mode; - uint16_t st_nlink; uint32_t st_uid; uint32_t st_gid; - uint32_t st_rdev; - char __pad2[4]; + uint32_t __pad0[4]; + uint64_t st_rdev; int64_t st_size; - int64_t st_atimeX; - int64_t st_mtimeX; - int64_t st_ctimeX; int64_t st_blksize; int64_t st_blocks; - uint64_t __unused4[2]; - } tgt_stat; + uint64_t st_atimeX; + uint64_t st_atime_nsec; + uint64_t st_mtimeX; + uint64_t st_mtime_nsec; + uint64_t st_ctimeX; + uint64_t st_ctime_nsec; + int64_t __unused[3]; + } tgt_stat64; static OpenFlagTransTable openFlagTable[]; -- cgit v1.2.3 From 65db30992c2462624b69fb1b1e737e0e84f9457d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 15:38:40 -0700 Subject: X86: Take into account the regular registers and the microcode registers when decided whether or not to fold. --HG-- extra : convert_revision : 26feec984dec61799c4afb03a4503a53c35872c5 --- src/arch/x86/isa/operands.isa | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 127e1b98a..eaedbdf17 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -96,12 +96,12 @@ def operand_types {{ }}; def operands {{ - 'SrcReg1': ('IntReg', 'uqw', '(((src1 & 0xC) == 4 ? foldOBit : 0) | src1)', 'IsInteger', 1), - 'SrcReg2': ('IntReg', 'uqw', '(((src2 & 0xC) == 4 ? foldOBit : 0) | src2)', 'IsInteger', 2), - 'Base': ('IntReg', 'uqw', '(((base & 0xC) == 4 ? foldABit : 0) | base)', 'IsInteger', 3), - 'Index': ('IntReg', 'uqw', '(((index & 0xC) == 4 ? foldABit : 0) | index)', 'IsInteger', 4), - 'DestReg': ('IntReg', 'uqw', '(((dest & 0xC) == 4 ? foldOBit : 0) | dest)', 'IsInteger', 5), - 'Data': ('IntReg', 'uqw', '(((data & 0xC) == 4 ? foldOBit : 0) | data)', 'IsInteger', 6), + 'SrcReg1': ('IntReg', 'uqw', '(((src1 & 0x1C) == 4 ? foldOBit : 0) | src1)', 'IsInteger', 1), + 'SrcReg2': ('IntReg', 'uqw', '(((src2 & 0x1C) == 4 ? foldOBit : 0) | src2)', 'IsInteger', 2), + 'Index': ('IntReg', 'uqw', '(((index & 0x1C) == 4 ? foldABit : 0) | index)', 'IsInteger', 3), + 'Base': ('IntReg', 'uqw', '(((base & 0x1C) == 4 ? foldABit : 0) | base)', 'IsInteger', 4), + 'DestReg': ('IntReg', 'uqw', '(((dest & 0x1C) == 4 ? foldOBit : 0) | dest)', 'IsInteger', 5), + 'Data': ('IntReg', 'uqw', '(((data & 0x1C) == 4 ? foldOBit : 0) | data)', 'IsInteger', 6), 'rax': ('IntReg', 'uqw', '(INTREG_RAX)', 'IsInteger', 7), 'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 10), 'ccFlagBits': ('IntReg', 'uqw', 'NUM_INTREGS + NumMicroIntRegs', None, 20), -- cgit v1.2.3 From 74fcf117ddcfe58c3b99f5f2a1209a1f7d306b07 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 15:39:25 -0700 Subject: X86: Allow RIP relative decode on -all- memory forms of operands. --HG-- extra : convert_revision : 8af62cda2ce1c4acfa26a028a4f7506647bc27f7 --- src/arch/x86/isa/specialize.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa index a45c6e80f..b5f51ab58 100644 --- a/src/arch/x86/isa/specialize.isa +++ b/src/arch/x86/isa/specialize.isa @@ -149,8 +149,8 @@ let {{ elif opType.tag == "M": # This refers to memory. The macroop constructor sets up modrm # addressing. Non memory modrm settings should cause an error. - Name += "_M" env.doModRM = True + return doRipRelativeDecode(Name, opTypes, env) elif opType.tag == None or opType.size == None: raise Exception, "Problem parsing operand tag: %s" % opType.tag elif opType.tag in ("C", "D", "G", "P", "S", "T", "V"): -- cgit v1.2.3 From 44c3419e1a0dbf6f222955f627b45192da2ad12e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 15:40:39 -0700 Subject: X86: Implement unsigned divide. The non-byte version ignores rdx which it shouldn't. --HG-- extra : convert_revision : 07e5509fb8ed9d73c144d6f52951ebc02e7c0032 --- .../isa/insts/arithmetic/multiply_and_divide.py | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src') 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 936fa6973..5355775eb 100644 --- a/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py +++ b/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py @@ -196,6 +196,53 @@ def macroop IMUL_R_P_I ld t2, ds, [0, t0, t7] mulel reg, t2, t1 }; + +# +# One byte version of unsigned division +# + +def macroop DIV_B_R +{ + div1 rax, rax, reg +}; + +def macroop DIV_B_M +{ + ld t1, ds, [scale, index, base], disp + div1 rax, rax, t1 +}; + +def macroop DIV_B_P +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + div1 rax, rax, t1 +}; + +# +# Unsigned division +# + +def macroop DIV_R +{ + divr rdx, rax, reg + divq rax, rax, reg +}; + +def macroop DIV_M +{ + ld t1, ds, [scale, index, base], disp + divr rdx, rax, t1 + divq rax, rax, t1 +}; + +def macroop DIV_P +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + divr rdx, rax, t1 + divq rax, rax, t1 +}; ''' #let {{ # class MUL(Inst): -- cgit v1.2.3 From 890e583163cd593cb683dc523dceab83fe9d6bc8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 15:41:08 -0700 Subject: X86: Set up RIP relative LEA instructions operands correctly. --HG-- extra : convert_revision : 820cafadd550487c0d62c5082261b0886fce4f0d --- src/arch/x86/isa/insts/load_effective_address.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/x86/isa/insts/load_effective_address.py b/src/arch/x86/isa/insts/load_effective_address.py index dcaf9778e..fc8b17629 100644 --- a/src/arch/x86/isa/insts/load_effective_address.py +++ b/src/arch/x86/isa/insts/load_effective_address.py @@ -60,6 +60,6 @@ def macroop LEA_R_M { def macroop LEA_R_P { rdip t7 - lea reg, ds, [scale, index, base], disp + lea reg, ds, [0, t0, t7], disp }; ''' -- cgit v1.2.3 From 43f0be52537a27f5e88e4740bde32b8d0654a868 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 15:42:04 -0700 Subject: X86: Use an mmap base address that matches what an actual machine uses. --HG-- extra : convert_revision : 98521797bbc6360301b3c6a6b1b8e28236ef570e --- src/arch/x86/process.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 6d30e53e3..036805612 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -127,9 +127,9 @@ X86LiveProcess::X86LiveProcess(const std::string &nm, ObjectFile *objFile, // for undertermined purposes. stack_base = (Addr)0x7FFFFFFFF000ULL; - // Set up region for mmaps. Tru64 seems to start just above 0 and - // grow up from there. - mmap_start = mmap_end = 0xfffff80000000000ULL; + // Set up region for mmaps. This was determined empirically and may not + // always be correct. + mmap_start = mmap_end = 0x2aaaaaaab000; } void X86LiveProcess::handleTrap(int trapNum, ThreadContext *tc) -- cgit v1.2.3 From f02bb6389485174fa19feebc54b523866550b6c6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 15:42:42 -0700 Subject: X86: Turn on the exit_group, exit, munmap, and write syscalls. --HG-- extra : convert_revision : e358c18cd999a8e274108e06502c3324c2d12d3b --- src/arch/x86/linux/syscalls.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 06509c974..efbe33dfa 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -82,7 +82,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, SyscallDesc X86LinuxProcess::syscallDescs[] = { /* 0 */ SyscallDesc("read", readFunc), - /* 1 */ SyscallDesc("write", unimplementedFunc), + /* 1 */ SyscallDesc("write", writeFunc), /* 2 */ SyscallDesc("open", openFunc), /* 3 */ SyscallDesc("close", closeFunc), /* 4 */ SyscallDesc("stat", unimplementedFunc), @@ -92,7 +92,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = { /* 8 */ SyscallDesc("lseek", unimplementedFunc), /* 9 */ SyscallDesc("mmap", mmapFunc), /* 10 */ SyscallDesc("mprotect", unimplementedFunc), - /* 11 */ SyscallDesc("munmap", unimplementedFunc), + /* 11 */ SyscallDesc("munmap", munmapFunc), /* 12 */ SyscallDesc("brk", obreakFunc), /* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc), /* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), @@ -141,7 +141,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = { /* 57 */ SyscallDesc("fork", unimplementedFunc), /* 58 */ SyscallDesc("vfork", unimplementedFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), - /* 60 */ SyscallDesc("exit", unimplementedFunc), + /* 60 */ SyscallDesc("exit", exitFunc), /* 61 */ SyscallDesc("wait4", unimplementedFunc), /* 62 */ SyscallDesc("kill", unimplementedFunc), /* 63 */ SyscallDesc("uname", unameFunc), @@ -312,7 +312,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = { /* 228 */ SyscallDesc("clock_gettime", unimplementedFunc), /* 229 */ SyscallDesc("clock_getres", unimplementedFunc), /* 230 */ SyscallDesc("clock_nanosleep", unimplementedFunc), - /* 231 */ SyscallDesc("exit_group", unimplementedFunc), + /* 231 */ SyscallDesc("exit_group", exitFunc), /* 232 */ SyscallDesc("epoll_wait", unimplementedFunc), /* 233 */ SyscallDesc("epoll_ctl", unimplementedFunc), /* 234 */ SyscallDesc("tgkill", unimplementedFunc), -- cgit v1.2.3 From 77482dc439b48e81b6c3ff7767d1ed02ebb4dbbc Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 15:43:20 -0700 Subject: X86: __pad0 should be a 4 byte pad, not a 4 long array of 4 byte pads. --HG-- extra : convert_revision : e0d5ab617bc95d5d714fa9fcdf0a448874aef886 --- src/arch/x86/linux/linux.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index d6dd81ab9..bde7925a9 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -71,7 +71,7 @@ class X86Linux64 : public Linux uint32_t st_mode; uint32_t st_uid; uint32_t st_gid; - uint32_t __pad0[4]; + uint32_t __pad0; uint64_t st_rdev; int64_t st_size; int64_t st_blksize; -- cgit v1.2.3 From 595ff465e5824d2ba82036b0316cd66ecbed2730 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 15:44:21 -0700 Subject: X86: Remove a naming conflict between the register index parameters and the "picked" register values. --HG-- extra : convert_revision : 7b2c1be509478153ebf396841e4cbeccee3e03d1 --- src/arch/x86/isa/microops/regop.isa | 104 ++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 9b7d74f50..3c562efc0 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -328,24 +328,24 @@ let {{ checkCCFlagBits = "checkCondition(ccFlagBits)" genCCFlagBits = \ - "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, src1, op2);" + "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, op2);" genCCFlagBitsSub = \ - "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, src1, ~op2, true);" + "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, ~op2, true);" genCCFlagBitsLogic = ''' //Don't have genFlags handle the OF or CF bits uint64_t mask = CFBit | OFBit; - ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, src1, op2); + ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, psrc1, 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); + IntReg psrc1 = pick(SrcReg1, 0, dataSize); + IntReg psrc2 = pick(SrcReg2, 1, dataSize); ''' immPick = ''' - IntReg src1 = pick(SrcReg1, 0, dataSize); + IntReg psrc1 = pick(SrcReg1, 0, dataSize); ''' @@ -360,7 +360,7 @@ let {{ # of the code, one with an integer operand, and one with an immediate # operand. matcher = re.compile("op2(?P\\.\\w+)?") - regCode = regPick + matcher.sub("src2", code) + regCode = regPick + matcher.sub("psrc2", code) immCode = immPick + matcher.sub("imm8", code) if not cc: @@ -369,7 +369,7 @@ let {{ flagCode = "" condCode = checkCCFlagBits - regFlagCode = matcher.sub("src2", flagCode) + regFlagCode = matcher.sub("psrc2", flagCode) immFlagCode = matcher.sub("imm8", flagCode) class RegOpChild(RegOp): @@ -411,7 +411,7 @@ let {{ # of the code, one with an integer operand, and one with an immediate # operand. matcher = re.compile("op2(?P\\.\\w+)?") - regCode = regPick + matcher.sub("src2", code) + regCode = regPick + matcher.sub("psrc2", code) immCode = immPick + matcher.sub("imm8", code) class RegOpChild(RegOp): @@ -468,66 +468,76 @@ let {{ setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code); - 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); - ''', + defineMicroRegOp('Add', 'DestReg = merge(DestReg, psrc1 + op2, dataSize)') + defineMicroRegOp('Or', 'DestReg = merge(DestReg, psrc1 | op2, dataSize);', flagCode = genCCFlagBitsLogic) defineMicroRegOp('Adc', ''' CCFlagBits flags = ccFlagBits; - DestReg = merge(DestReg, src1 + op2 + flags.CF, dataSize); + DestReg = merge(DestReg, psrc1 + op2 + flags.CF, dataSize); ''') defineMicroRegOp('Sbb', ''' CCFlagBits flags = ccFlagBits; - DestReg = merge(DestReg, src1 - op2 - flags.CF, dataSize); + DestReg = merge(DestReg, psrc1 - op2 - flags.CF, dataSize); ''', flagCode = genCCFlagBitsSub) defineMicroRegOp('And', \ - 'DestReg = merge(DestReg, src1 & op2, dataSize)', \ + 'DestReg = merge(DestReg, psrc1 & op2, dataSize)', \ flagCode = genCCFlagBitsLogic) defineMicroRegOp('Sub', \ - 'DestReg = merge(DestReg, src1 - op2, dataSize)', \ + 'DestReg = merge(DestReg, psrc1 - op2, dataSize)', \ flagCode = genCCFlagBitsSub) defineMicroRegOp('Xor', \ - 'DestReg = merge(DestReg, src1 ^ op2, dataSize)', \ + 'DestReg = merge(DestReg, psrc1 ^ op2, dataSize)', \ flagCode = genCCFlagBitsLogic) defineMicroRegOp('Mul1s', ''' int signPos = (dataSize * 8) / 2 - 1; - IntReg srcVal1 = src1 | (-bits(src1, signPos) << signPos); - IntReg srcVal2 = op2 | (-bits(src1, signPos) << signPos); + IntReg srcVal1 = psrc1 | (-bits(psrc1, signPos) << signPos); + IntReg srcVal2 = op2 | (-bits(psrc1, signPos) << signPos); DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize) ''') defineMicroRegOp('Mul1u', ''' int halfSize = (dataSize * 8) / 2; - IntReg srcVal1 = src1 & mask(halfSize); + IntReg srcVal1 = psrc1 & mask(halfSize); IntReg srcVal2 = op2 & mask(halfSize); DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize) ''') defineMicroRegOp('Mulel', \ - 'DestReg = merge(DestReg, src1 * op2, dataSize)') + 'DestReg = merge(DestReg, psrc1 * 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 psrc1_h = psrc1 >> halfSize; + uint64_t psrc1_l = psrc1 & mask(halfSize); + uint64_t psrc2_h = op2 >> halfSize; + uint64_t psrc2_l = op2 & mask(halfSize); uint64_t result = - ((src1_l * src2_h) >> halfSize) + - ((src1_h * src2_l) >> halfSize) + - src1_h * src2_h; + ((psrc1_l * psrc2_h) >> halfSize) + + ((psrc1_h * psrc2_l) >> halfSize) + + psrc1_h * psrc2_h; DestReg = merge(DestReg, result, dataSize); ''') + defineMicroRegOp('Div1', ''' + int halfSize = (dataSize * 8) / 2; + IntReg quotient = (psrc1 / op2) & mask(halfSize); + IntReg remainder = (psrc1 % op2) & mask(halfSize); + IntReg result = quotient | (remainder << halfSize); + DestReg = merge(DestReg, result, dataSize); + ''') + defineMicroRegOp('Divq', ''' + DestReg = merge(DestReg, psrc1 / op2, dataSize); + ''') + defineMicroRegOp('Divr', ''' + DestReg = merge(DestReg, psrc1 % op2, dataSize); + ''') + # - # HACK HACK HACK HACK - Put src1 in here but make it inert to shut up gcc. + # HACK HACK HACK HACK - Put psrc1 in here but make it inert to shut up gcc. # - defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, src1 * 0 + op2, dataSize)', + defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, psrc1 * 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, src1 << shiftAmt, dataSize); + DestReg = merge(DestReg, psrc1 << shiftAmt, dataSize); ''') defineMicroRegOp('Srl', ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); @@ -535,7 +545,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, (src1 >> shiftAmt) & logicalMask, dataSize); + DestReg = merge(DestReg, (psrc1 >> shiftAmt) & logicalMask, dataSize); ''') defineMicroRegOp('Sra', ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); @@ -544,15 +554,15 @@ let {{ // them manually to be sure. uint64_t arithMask = -bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt); - DestReg = merge(DestReg, (src1 >> shiftAmt) | arithMask, dataSize); + DestReg = merge(DestReg, (psrc1 >> shiftAmt) | arithMask, dataSize); ''') defineMicroRegOp('Ror', ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); if(shiftAmt) { - uint64_t top = src1 << (dataSize * 8 - shiftAmt); - uint64_t bottom = bits(src1, dataSize * 8, shiftAmt); + uint64_t top = psrc1 << (dataSize * 8 - shiftAmt); + uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt); DestReg = merge(DestReg, top | bottom, dataSize); } else @@ -566,8 +576,8 @@ let {{ CCFlagBits flags = ccFlagBits; uint64_t top = flags.CF << (dataSize * 8 - shiftAmt); if(shiftAmt > 1) - top |= src1 << (dataSize * 8 - shiftAmt - 1); - uint64_t bottom = bits(src1, dataSize * 8, shiftAmt); + top |= psrc1 << (dataSize * 8 - shiftAmt - 1); + uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt); DestReg = merge(DestReg, top | bottom, dataSize); } else @@ -578,9 +588,9 @@ let {{ (op2 & ((dataSize == 8) ? mask(6) : mask(5))); if(shiftAmt) { - uint64_t top = src1 << shiftAmt; + uint64_t top = psrc1 << shiftAmt; uint64_t bottom = - bits(src1, dataSize * 8 - 1, dataSize * 8 - shiftAmt); + bits(psrc1, dataSize * 8 - 1, dataSize * 8 - shiftAmt); DestReg = merge(DestReg, top | bottom, dataSize); } else @@ -592,11 +602,11 @@ let {{ if(shiftAmt) { CCFlagBits flags = ccFlagBits; - uint64_t top = src1 << shiftAmt; + uint64_t top = psrc1 << shiftAmt; uint64_t bottom = flags.CF << (shiftAmt - 1); if(shiftAmt > 1) bottom |= - bits(src1, dataSize * 8 - 1, + bits(psrc1, dataSize * 8 - 1, dataSize * 8 - shiftAmt + 1); DestReg = merge(DestReg, top | bottom, dataSize); } @@ -604,15 +614,15 @@ let {{ DestReg = DestReg; ''') - defineMicroRegOpWr('Wrip', 'RIP = src1 + op2', elseCode="RIP = RIP;") + defineMicroRegOpWr('Wrip', 'RIP = psrc1 + op2', elseCode="RIP = RIP;") defineMicroRegOpRd('Rdip', 'DestReg = RIP') defineMicroRegOpImm('Sext', ''' - IntReg val = src1; + IntReg val = psrc1; 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(src1, imm8-1, 0);') + defineMicroRegOpImm('Zext', 'DestReg = bits(psrc1, imm8-1, 0);') }}; -- cgit v1.2.3 From 463e8a7516240e49706fd71bc9f84060d5f9b3a5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 15:44:48 -0700 Subject: X86: Attach the "DIV" instruction implementation to the decoder. --HG-- extra : convert_revision : 8aef1c8d1ced2db998ed0d31241cadc17e19eadd --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 3253c9fec..507f75bb8 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -521,7 +521,8 @@ 0x3: Inst::NEG(Eb); 0x4: Inst::MUL_B(Eb); 0x5: Inst::IMUL_B(Eb); - 0x6: div_Eb(); + //This should be Eb, but it access the entire word value ax. + 0x6: Inst::DIV_B(Ew); 0x7: idiv_Eb(); } //0x7: group3_Ev(); @@ -532,7 +533,7 @@ 0x3: Inst::NEG(Ev); 0x4: Inst::MUL(Ev); 0x5: Inst::IMUL(Ev); - 0x6: div_Ev(); + 0x6: Inst::DIV(Ev); 0x7: idiv_Ev(); } } -- cgit v1.2.3 From ae3e1d22fc3bfff8c246a0a743b77f4096d95b74 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 30 Jul 2007 17:54:01 -0700 Subject: X86: Add decoding for x87 floating point. --HG-- extra : convert_revision : 08f0f4a3d77a2c5eb9b5ca0cae7d0be9a72febec --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 11 +- src/arch/x86/isa/decoder/x87.isa | 346 ++++++++++++++++++++++++++ 2 files changed, 347 insertions(+), 10 deletions(-) create mode 100644 src/arch/x86/isa/decoder/x87.isa (limited to 'src') diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 507f75bb8..7c627b0c2 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -470,16 +470,7 @@ } 0x7: xlat(); } - 0x1B: decode OPCODE_OP_BOTTOM3 { - 0x0: esc0(); - 0x1: esc1(); - 0x2: esc2(); - 0x3: esc3(); - 0x4: esc4(); - 0x5: esc5(); - 0x6: esc6(); - 0x7: esc7(); - } + ##include "x87.isa" 0x1C: decode OPCODE_OP_BOTTOM3 { 0x0: loopne_Jb(); 0x1: loope_Jb(); diff --git a/src/arch/x86/isa/decoder/x87.isa b/src/arch/x86/isa/decoder/x87.isa new file mode 100644 index 000000000..f16647fe5 --- /dev/null +++ b/src/arch/x86/isa/decoder/x87.isa @@ -0,0 +1,346 @@ +// Copyright (c) 2007 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. Redistributions +// in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or +// other materials provided with the distribution. Neither the name of +// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Gabe Black + +0x1B: decode OPCODE_OP_BOTTOM3 { + //0x0: esc0(); + 0x0: decode MODRM_REG { + 0x0: fadd(); + 0x1: fmul(); + 0x2: fcom(); + 0x3: fcomp(); + 0x4: fsub(); + 0x5: fsubr(); + 0x6: fdiv(); + 0x7: fdivr(); + } + //0x1: esc1(); + 0x1: decode MODRM_REG { + 0x0: fld(); + 0x1: decode MODRM_MOD { + 0x3: fxch(); + default: Inst::UD2(); + } + 0x2: decode MODRM_MOD { + 0x3: decode MODRM_RM { + 0x0: fnop(); + default: Inst::UD2(); + } + default: fst(); + } + 0x3: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fstp(); + } + 0x4: decode MODRM_MOD { + 0x3: decode MODRM_RM { + 0x0: fchs(); + 0x1: fabs(); + 0x4: ftst(); + 0x5: fxam(); + default: Inst::UD2(); + } + default: fldenv(); + } + 0x5: decode MODRM_MOD { + 0x3: decode MODRM_RM { + 0x0: fld1(); + 0x1: fldl2t(); + 0x2: fldl2e(); + 0x3: fldpi(); + 0x4: fldlg2(); + 0x5: fldln2(); + 0x6: fldz(); + } + default: fldcw(); + } + 0x6: decode MODRM_MOD { + 0x3: decode MODRM_RM { + 0x0: f2xm1(); + 0x1: fyl2x(); + 0x2: fptan(); + 0x3: fpatan(); + 0x4: fxtract(); + 0x5: fprem1(); + 0x6: fdecstp(); + 0x7: fincstp(); + } + default: fnstenv(); + } + 0x7: decode MODRM_MOD { + 0x3: decode MODRM_RM { + 0x0: fprem(); + 0x1: fyl2xp1(); + 0x2: fsqrt(); + 0x3: fsincos(); + 0x4: frndint(); + 0x5: fscale(); + 0x6: fsin(); + 0x7: fcos(); + } + default: fnstcw(); + } + } + //0x2: esc2(); + 0x2: decode MODRM_REG { + 0x0: decode MODRM_MOD { + 0x3: fcmovb(); + default: fiadd(); + } + 0x1: decode MODRM_MOD { + 0x3: fcmove(); + default: fimul(); + } + 0x2: decode MODRM_MOD { + 0x3: fcmovbe(); + default: ficom(); + } + 0x3: decode MODRM_MOD { + 0x3: fcmovu(); + default: ficomp(); + } + 0x4: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fisub(); + } + 0x5: decode MODRM_MOD { + 0x3: decode MODRM_RM { + 0x1: fucompp(); + default: Inst::UD2(); + } + default: fisubr(); + } + 0x6: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fidiv(); + } + 0x7: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fidivr(); + } + } + //0x3: esc3(); + 0x3: decode MODRM_REG { + 0x0: decode MODRM_MOD { + 0x3: fcmovnb(); + default: fild(); + } + 0x1: decode MODRM_MOD { + 0x3: fcmovne(); + default: fisttp(); + } + 0x2: decode MODRM_MOD { + 0x3: fcmovnbe(); + default: fist(); + } + 0x3: decode MODRM_MOD { + 0x3: fcmovnu(); + default: fistp(); + } + 0x4: decode MODRM_MOD { + 0x3: decode MODRM_RM { + 0x2: fnclex(); + 0x3: fninit(); + default: Inst::UD2(); + } + default: Inst::UD2(); + } + 0x5: decode MODRM_MOD { + 0x3: fucomi(); + default: fld(); + } + 0x6: decode MODRM_MOD { + 0x3: fcomi(); + default: Inst::UD2(); + } + 0x7: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fstp(); + } + } + //0x4: esc4(); + 0x4: decode MODRM_REG { + 0x0: fadd(); + 0x1: fmul(); + 0x2: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fcom(); + } + 0x3: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fcomp(); + } + 0x4: decode MODRM_MOD { + 0x3: fsubr(); + default: fsub(); + } + 0x5: decode MODRM_MOD { + 0x3: fsub(); + default: fsubr(); + } + 0x6: decode MODRM_MOD { + 0x3: fdivr(); + default: fdiv(); + } + 0x7: decode MODRM_MOD { + 0x3: fdiv(); + default: fdivr(); + } + } + //0x5: esc5(); + 0x5: decode MODRM_REG { + 0x0: decode MODRM_MOD { + 0x3: ffree(); + default: fld(); + } + 0x1: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fisttp(); + } + 0x2: fst(); + 0x3: fstp(); + 0x4: decode MODRM_MOD { + 0x3: fucom(); + default: frstor(); + } + 0x5: decode MODRM_MOD { + 0x3: fucomp(); + default: Inst::UD2(); + } + 0x6: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fnsave(); + } + 0x7: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fnstsw(); + } + } + //0x6: esc6(); + 0x6: decode MODRM_REG { + 0x0: decode MODRM_MOD { + 0x3: faddp(); + default: fiadd(); + } + 0x1: decode MODRM_MOD { + 0x3: fmulp(); + default: fimul(); + } + 0x2: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: ficom(); + } + 0x3: decode MODRM_MOD { + 0x3: decode MODRM_RM { + 0x1: fcompp(); + default: Inst::UD2(); + } + default: ficomp(); + } + 0x4: decode MODRM_MOD { + 0x3: fsubrp(); + default: fisub(); + } + 0x5: decode MODRM_MOD { + 0x3: fsubp(); + default: fisubr(); + } + 0x6: decode MODRM_MOD { + 0x3: fdivrp(); + default: fidiv(); + } + 0x7: decode MODRM_MOD { + 0x3: fdivp(); + default: fidivr(); + } + } + //0x7: esc7(); + 0x7: decode MODRM_REG { + 0x0: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fild(); + } + 0x1: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fisttp(); + } + 0x2: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fist(); + } + 0x3: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fistp(); + } + 0x4: decode MODRM_MOD { + 0x3: decode MODRM_RM { + 0x0: fnstsw(); + default: Inst::UD2(); + } + default: fbld(); + } + 0x5: decode MODRM_MOD { + 0x3: fucomip(); + default: fild(); + } + 0x6: decode MODRM_MOD { + 0x3: fcomip(); + default: fbstp(); + } + 0x7: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fistp(); + } + } +} -- cgit v1.2.3