From 1ed6a8ed79d9a89437d47d52390aa5c7a8ebd5d5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 16:39:07 -0700 Subject: [PATCH] Define and fill out a lot of different instructions and instruction versions. Added two of the shift microops. --HG-- extra : convert_revision : 0b76953dbb1dc3366242d4d209cccebde86bbe4e --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 110 +++++++++++------- .../isa/insts/arithmetic/add_and_subtract.py | 66 +++++++++++ .../x86/isa/insts/compare_and_test/compare.py | 46 ++++++++ .../x86/isa/insts/control_transfer/jump.py | 10 ++ src/arch/x86/isa/insts/logical.py | 106 +++++++++++++++++ .../x86/isa/insts/rotate_and_shift/shift.py | 22 +++- src/arch/x86/isa/microops/regop.isa | 12 +- 7 files changed, 331 insertions(+), 41 deletions(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index b897a225b..80031a7fc 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -61,8 +61,6 @@ 0x1: decode OPCODE_OP_TOP5 { format WarnUnimpl { 0x00: decode OPCODE_OP_BOTTOM3 { - 0x4: ADD(); - 0x5: ADD(); 0x6: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: push_ES(); @@ -71,15 +69,12 @@ 0x0: This_should_be_an_illegal_instruction(); default: pop_ES(); } - default: ADD(); + default: MultiInst::ADD(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x01: decode OPCODE_OP_BOTTOM3 { - 0x0: or_Eb_Gb(); - 0x1: or_Ev_Gv(); - 0x2: or_Gb_Eb(); - 0x3: or_Gv_Ev(); - 0x4: or_Al_Ib(); - 0x5: or_rAX_Iz(); 0x6: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: push_CS(); @@ -87,6 +82,10 @@ //Any time this is seen, it should generate a two byte opcode 0x7: M5InternalError::error( {{"Saw a one byte opcode whose value was 0x0F!"}}); + default: MultiInst::OR(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x02: decode OPCODE_OP_BOTTOM3 { 0x0: adc_Eb_Gb(); @@ -121,33 +120,27 @@ } } 0x04: decode OPCODE_OP_BOTTOM3 { - 0x0: and_Eb_Gb(); - 0x1: and_Ev_Gv(); - 0x2: and_Gb_Eb(); - 0x3: and_Gv_Ev(); - 0x4: and_Al_Ib(); - 0x5: and_rAX_Iz(); 0x6: M5InternalError::error( {{"Tried to execute the ES segment override prefix!"}}); 0x7: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: daa(); } + default: MultiInst::AND(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x05: decode OPCODE_OP_BOTTOM3 { - 0x0: sub_Eb_Gb(); - 0x1: sub_Ev_Gv(); - 0x2: sub_Gb_Eb(); - 0x3: sub_Gv_Ev(); - 0x4: sub_Al_Ib(); - 0x5: sub_rAX_Iz(); 0x6: M5InternalError::error( {{"Tried to execute the CS segment override prefix!"}}); 0x7: das(); + default: MultiInst::SUB(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x06: decode OPCODE_OP_BOTTOM3 { - 0x4: Inst::XOR(rAl,Ib); - 0x5: Inst::XOR(rAx,Iz); 0x6: M5InternalError::error( {{"Tried to execute the SS segment override prefix!"}}); 0x7: decode MODE_SUBMODE { @@ -156,21 +149,20 @@ } default: MultiInst::XOR(OPCODE_OP_BOTTOM3, [Eb,Gb], [Ev,Gv], - [Gb,Eb], [Gv,Ev]); + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x07: decode OPCODE_OP_BOTTOM3 { - 0x0: cmp_Eb_Gb(); - 0x1: cmp_Ev_Gv(); - 0x2: cmp_Gb_Eb(); - 0x3: cmp_Gv_Ev(); - 0x4: Inst::CMP(rAl,Ib); - 0x5: Inst::CMP(rAX,Iz); 0x6: M5InternalError::error( {{"Tried to execute the DS segment override prefix!"}}); 0x7: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: aas(); } + default: MultiInst::CMP(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x08: decode MODE_SUBMODE { 0x0: M5InternalError::error ( @@ -276,10 +268,20 @@ 0x4: jl_Jb(); 0x5: jnl_Jb(); 0x6: jle_Jb(); - 0x7: jnke_Jb(); + 0x7: Inst::JNLE(Jb); } 0x10: decode OPCODE_OP_BOTTOM3 { - 0x0: group1_Eb_Ib(); + //0x0: group1_Eb_Ib(); + 0x0: decode MODRM_REG { + 0x0: Inst::ADD(Eb,Ib); + 0x1: Inst::OR(Eb,Ib); + 0x2: adc_Eb_Ib(); + 0x3: sbb_Eb_Ib(); + 0x4: Inst::AND(Eb,Ib); + 0x5: Inst::SUB(Eb,Ib); + 0x6: Inst::XOR(Eb,Ib); + 0x7: Inst::CMP(Eb,Ib); + } //0x1: group1_Ev_Iz(); 0x1: decode MODRM_REG { 0x0: add_Ev_Iz(); @@ -289,11 +291,21 @@ 0x4: Inst::AND(Ev,Iz); 0x5: Inst::SUB(Ev,Iz); 0x6: xor_Ev_Iz(); - 0x7: cmp_Ev_Iz(); + 0x7: Inst::CMP(Ev,Iz); } 0x2: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); - default: group1_Eb_Ib(); + //default: group1_Eb_Ib(); + default: decode MODRM_REG { + 0x0: Inst::ADD(Eb,Ib); + 0x1: Inst::OR(Eb,Ib); + 0x2: adc_Eb_Ib(); + 0x3: sbb_Eb_Ib(); + 0x4: Inst::AND(Eb,Ib); + 0x5: Inst::SUB(Eb,Ib); + 0x6: Inst::XOR(Eb,Ib); + 0x7: Inst::CMP(Eb,Ib); + } } //0x3: group1_Ev_Ib(); 0x3: decode MODRM_REG { @@ -304,7 +316,7 @@ 0x4: Inst::AND(Ev,Ib); 0x5: sub_Ev_Ib(); 0x6: xor_Ev_Ib(); - 0x7: cmp_Ev_Ib(); + 0x7: Inst::CMP(Ev,Ib); } 0x4: Inst::TEST(Eb,Gb); 0x5: Inst::TEST(Ev,Gv); @@ -322,10 +334,10 @@ 0x7: group10_Ev(); //Make sure this is Ev } 0x12: decode OPCODE_OP_BOTTOM3 { - default: Inst::NOP(); //XXX repe makes this a "pause" + 0x0: Inst::NOP(); //XXX repe makes this a "pause" 0x1: xchg_rCX_rAX(); 0x2: xchg_rDX_rAX(); - 0x3: xchg_rVX_rAX(); + 0x3: xchg_rBX_rAX(); 0x4: xchg_rSP_rAX(); 0x5: xchg_rBP_rAX(); 0x6: xchg_rSI_rAX(); @@ -395,8 +407,28 @@ } } 0x18: decode OPCODE_OP_BOTTOM3 { - 0x0: group2_Eb_Ib(); - 0x1: group2_Ev_Ib(); + //0x0: group2_Eb_Ib(); + 0x0: decode MODRM_REG { + 0x0: rol_Eb_Ib(); + 0x1: ror_Eb_Ib(); + 0x2: rcl_Eb_Ib(); + 0x3: rcr_Eb_Ib(); + 0x4: Inst::SAL(Eb,Ib); + 0x5: shr_Eb_Ib(); + 0x6: Inst::SAL(Eb,Ib); + 0x7: sar_Eb_Ib(); + } + //0x1: group2_Ev_Ib(); + 0x1: decode MODRM_REG { + 0x0: rol_Ev_Ib(); + 0x1: ror_Ev_Ib(); + 0x2: rcl_Ev_Ib(); + 0x3: rcr_Ev_Ib(); + 0x4: Inst::SAL(Ev,Ib); + 0x5: shr_Ev_Ib(); + 0x6: Inst::SAL(Ev,Ib); + 0x7: sar_Ev_Ib(); + } 0x2: ret_near_Iw(); 0x3: Inst::RET_NEAR(); 0x4: decode MODE_SUBMODE { 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 4d6e40c74..a8bad4653 100644 --- a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py +++ b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py @@ -54,6 +54,11 @@ # Authors: Gabe Black microcode = ''' +def macroop ADD_R_R +{ + add reg, reg, regm +}; + def macroop ADD_R_I { limm t1, imm @@ -77,12 +82,58 @@ def macroop ADD_P_I st t1, ds, [scale, index, base], disp }; +def macroop ADD_M_R +{ + ld t1, ds, [scale, index, base], disp + add t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop ADD_P_R +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + add t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop ADD_R_M +{ + ld t1, ds, [scale, index, base], disp + add reg, reg, t1 +}; + +def macroop ADD_R_P +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + add reg, reg, t1 +}; + +def macroop SUB_R_R +{ + sub reg, reg, regm +}; + def macroop SUB_R_I { limm t1, imm sub reg, reg, t1 }; +def macroop SUB_R_M +{ + ld t1, ds, [scale, index, base], disp + sub reg, reg, t1 +}; + +def macroop SUB_R_P +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + sub reg, reg, t1 +}; + def macroop SUB_M_I { limm t2, imm @@ -99,6 +150,21 @@ def macroop SUB_P_I sub t1, t1, t2 st t1, ds, [scale, index, base], disp }; + +def macroop SUB_M_R +{ + ld t1, ds, [scale, index, base], disp + sub t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop SUB_P_R +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + sub t1, t1, reg + st t1, ds, [scale, index, base], disp +}; ''' #let {{ # class ADC(Inst): diff --git a/src/arch/x86/isa/insts/compare_and_test/compare.py b/src/arch/x86/isa/insts/compare_and_test/compare.py index ba421a520..8f5890b23 100644 --- a/src/arch/x86/isa/insts/compare_and_test/compare.py +++ b/src/arch/x86/isa/insts/compare_and_test/compare.py @@ -54,6 +54,52 @@ # Authors: Gabe Black microcode = ''' +def macroop CMP_R_M +{ + ld t1, ds, [scale, index, base], disp + sub t0, reg, t1, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_R_P +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + sub t0, reg, t1, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_M_I +{ + limm t2, imm + ld t1, ds, [scale, index, base], disp + sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_P_I +{ + limm t2, imm + rdip t7 + ld t1, ds, [0, t0, t7], disp + sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_M_R +{ + ld t1, ds, [scale, index, base], disp + sub t0, t1, reg, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_P_R +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + sub t0, t1, reg, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_R_R +{ + sub t0, reg, regm, flags=(OF, SF, ZF, AF, PF, CF) +}; + def macroop CMP_R_I { limm t1, imm diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py index b191730d5..3d69643ae 100644 --- a/src/arch/x86/isa/insts/control_transfer/jump.py +++ b/src/arch/x86/isa/insts/control_transfer/jump.py @@ -104,6 +104,16 @@ def macroop JNBE_I wrip t1, t2, flags=(nCCvZF,) }; +def macroop JNLE_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(nCSxOvZF,) +}; + def macroop JMP_I { # Make the default data size of jumps 64 bits in 64 bit mode diff --git a/src/arch/x86/isa/insts/logical.py b/src/arch/x86/isa/insts/logical.py index 2fd369d60..f99638cac 100644 --- a/src/arch/x86/isa/insts/logical.py +++ b/src/arch/x86/isa/insts/logical.py @@ -54,6 +54,62 @@ # Authors: Gabe Black microcode = ''' +def macroop OR_R_R +{ + or reg, reg, regm +}; + +def macroop OR_M_I +{ + limm t2, imm + ld t1, ds, [scale, index, base], disp + or t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + +def macroop OR_P_I +{ + limm t2, imm + rdip t7 + ld t1, ds, [0, t0, t7], disp + or t1, t1, t2 + st t1, ds, [0, t0, t7], disp +}; + +def macroop OR_M_R +{ + ld t1, ds, [scale, index, base], disp + or t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop OR_P_R +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + or t1, t1, reg + st t1, ds, [0, t0, t7], disp +}; + +def macroop OR_R_M +{ + ld t1, ds, [scale, index, base], disp + or reg, reg, t1 +}; + +def macroop OR_R_P +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + or reg, reg, t1 +}; + +def macroop OR_R_I +{ + limm t1, imm + or reg, reg, t1 +}; + def macroop XOR_R_R { xor reg, reg, regm @@ -65,6 +121,23 @@ def macroop XOR_R_I xor reg, reg, t1 }; +def macroop XOR_M_I +{ + limm t2, imm + ld t1, ds, [scale, index, base], disp + xor t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + +def macroop XOR_P_I +{ + limm t2, imm + rdip t7 + ld t1, ds, [scale, index, base], disp + xor t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + def macroop XOR_M_R { ld t1, ds, [scale, index, base], disp @@ -93,6 +166,24 @@ def macroop XOR_R_P xor reg, reg, t1 }; +def macroop AND_R_R +{ + and reg, reg, regm +}; + +def macroop AND_R_M +{ + ld t1, ds, [scale, index, base], disp + and reg, reg, t1 +}; + +def macroop AND_R_P +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + and reg, reg, t1 +}; + def macroop AND_R_I { limm t1, imm @@ -115,6 +206,21 @@ def macroop AND_P_I and t2, t2, t1 st t2, ds, [scale, index, base], disp }; + +def macroop AND_M_R +{ + ld t1, ds, [scale, index, base], disp + and t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop AND_P_R +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + and t1, t1, reg + st t1, ds, [scale, index, base], disp +}; ''' #let {{ #microcodeString = ''' diff --git a/src/arch/x86/isa/insts/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/rotate_and_shift/shift.py index f72794657..b1c86a921 100644 --- a/src/arch/x86/isa/insts/rotate_and_shift/shift.py +++ b/src/arch/x86/isa/insts/rotate_and_shift/shift.py @@ -53,7 +53,27 @@ # # Authors: Gabe Black -microcode = "" +microcode = ''' +def macroop SAL_R_I +{ + sll reg, reg, imm +}; + +def macroop SAL_M_I +{ + ld t1, ds, [scale, index, base], disp + sll t1, t1, imm + st t1, ds, [scale, index, base], disp +}; + +def macroop SAL_P_I +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + sll t1, t1, imm + st t1, ds, [0, t0, t7], disp +}; +''' #let {{ # class SAL(Inst): # "GenFault ${new UnimpInstFault}" diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index a0e8adc9a..31ca8344d 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -389,10 +389,20 @@ let {{ defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True) defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)') defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True) - defineMicroRegOp('mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)') + defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)') defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', elseCode='DestReg=DestReg;', cc=True) + # Shift instructions + defineMicroRegOp('Sll', ''' + uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3))); + DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize); + ''') + # There are special rules for the flag for a single bit shift + defineMicroRegOp('Bll', ''' + DestReg = merge(DestReg, SrcReg1 << 1, dataSize); + ''') + # This has it's own function because Wr ops have implicit destinations def defineMicroRegOpWr(mnemonic, code, elseCode=";"): Name = mnemonic