diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/isa/decoder/one_byte_opcodes.isa | 671 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/x87.isa | 546 | ||||
-rw-r--r-- | src/arch/x86/isa/formats/string.isa | 2 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/general_purpose/compare_and_test/bounds.py | 19 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/general_purpose/compare_and_test/set_byte_on_condition.py | 5 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/general_purpose/control_transfer/conditional_jump.py | 7 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/general_purpose/control_transfer/loop.py | 24 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py | 14 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/general_purpose/input_output/general_io.py | 32 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/general_purpose/input_output/string_io.py | 96 | ||||
-rw-r--r-- | src/arch/x86/isa/macroop.isa | 22 | ||||
-rw-r--r-- | src/arch/x86/isa/microasm.isa | 9 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 2 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/specop.isa | 118 | ||||
-rw-r--r-- | src/arch/x86/x86_traits.hh | 1 |
15 files changed, 885 insertions, 683 deletions
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index da7867401..4365c23fd 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -59,15 +59,15 @@ // 0x1: decode OPCODE_OP_TOP5 { - format WarnUnimpl { + format Inst { 0x00: decode OPCODE_OP_BOTTOM3 { 0x6: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: push_ES(); + 0x0: UD2(); + default: WarnUnimpl::push_ES(); } 0x7: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: pop_ES(); + 0x0: UD2(); + default: WarnUnimpl::pop_ES(); } default: MultiInst::ADD(OPCODE_OP_BOTTOM3, [Eb,Gb], [Ev,Gv], @@ -76,8 +76,8 @@ } 0x01: decode OPCODE_OP_BOTTOM3 { 0x6: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: push_CS(); + 0x0: UD2(); + default: WarnUnimpl::push_CS(); } //Any time this is seen, it should generate a two byte opcode 0x7: M5InternalError::error( @@ -89,12 +89,12 @@ } 0x02: decode OPCODE_OP_BOTTOM3 { 0x6: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: push_SS(); + 0x0: UD2(); + default: WarnUnimpl::push_SS(); } 0x7: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: pop_SS(); + 0x0: UD2(); + default: WarnUnimpl::pop_SS(); } default: MultiInst::ADC(OPCODE_OP_BOTTOM3, [Eb,Gb], [Ev,Gv], @@ -103,12 +103,12 @@ } 0x03: decode OPCODE_OP_BOTTOM3 { 0x6: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: push_DS(); + 0x0: UD2(); + default: WarnUnimpl::push_DS(); } 0x7: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: pop_DS(); + 0x0: UD2(); + default: WarnUnimpl::pop_DS(); } default: MultiInst::SBB(OPCODE_OP_BOTTOM3, [Eb,Gb], [Ev,Gv], @@ -119,8 +119,8 @@ 0x6: M5InternalError::error( {{"Tried to execute the ES segment override prefix!"}}); 0x7: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: daa(); + 0x0: UD2(); + default: WarnUnimpl::daa(); } default: MultiInst::AND(OPCODE_OP_BOTTOM3, [Eb,Gb], [Ev,Gv], @@ -130,7 +130,10 @@ 0x05: decode OPCODE_OP_BOTTOM3 { 0x6: M5InternalError::error( {{"Tried to execute the CS segment override prefix!"}}); - 0x7: das(); + 0x7: decode MODE_SUBMODE { + 0x0: UD2(); + default: WarnUnimpl::das(); + } default: MultiInst::SUB(OPCODE_OP_BOTTOM3, [Eb,Gb], [Ev,Gv], [Gb,Eb], [Gv,Ev], @@ -140,8 +143,8 @@ 0x6: M5InternalError::error( {{"Tried to execute the SS segment override prefix!"}}); 0x7: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: aaa(); + 0x0: UD2(); + default: WarnUnimpl::aaa(); } default: MultiInst::XOR(OPCODE_OP_BOTTOM3, [Eb,Gb], [Ev,Gv], @@ -152,47 +155,45 @@ 0x6: M5InternalError::error( {{"Tried to execute the DS segment override prefix!"}}); 0x7: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: aas(); + 0x0: UD2(); + default: WarnUnimpl::aas(); } default: MultiInst::CMP(OPCODE_OP_BOTTOM3, [Eb,Gb], [Ev,Gv], [Gb,Eb], [Gv,Ev], [rAb,Ib], [rAv,Iz]); } - format Inst { - 0x08: decode MODE_SUBMODE { - 0x0: M5InternalError::error ( - {{"Tried to execute an REX prefix!"}}); - default: INC(Bv); - } - 0x09: decode MODE_SUBMODE { - 0x0: M5InternalError::error ( - {{"Tried to execute an REX prefix!"}}); - default: DEC(Bv); - } - 0x0A: PUSH(Bv); - 0x0B: POP(Bv); + 0x08: decode MODE_SUBMODE { + 0x0: M5InternalError::error ( + {{"Tried to execute an REX prefix!"}}); + default: INC(Bv); + } + 0x09: decode MODE_SUBMODE { + 0x0: M5InternalError::error ( + {{"Tried to execute an REX prefix!"}}); + default: DEC(Bv); } + 0x0A: PUSH(Bv); + 0x0B: POP(Bv); 0x0C: decode OPCODE_OP_BOTTOM3 { 0x0: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: Inst::PUSHA(); + 0x0: UD2(); + default: PUSHA(); } 0x1: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: Inst::POPA(); + 0x0: UD2(); + default: POPA(); } 0x2: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: bound_Gv_Ma(); + 0x0: UD2(); + default: BOUND(Gv,Mv); } 0x3: decode MODE_SUBMODE { //The second operand should really be of size "d", but it's //set to "v" in order to have a consistent register size. //This shouldn't affect behavior. - 0x0: Inst::MOVSXD(Gv,Ev); - default: arpl_Ew_Gw(); + 0x0: MOVSXD(Gv,Ev); + default: WarnUnimpl::arpl_Ew_Gw(); } 0x4: M5InternalError::error( {{"Tried to execute the FS segment override prefix!"}}); @@ -204,41 +205,62 @@ {{"Tried to execute the DS address size override prefix!"}}); } 0x0D: decode OPCODE_OP_BOTTOM3 { - 0x0: Inst::PUSH(Iz); - 0x1: Inst::IMUL(Gv,Ev,Iz); - 0x2: Inst::PUSH(Ib); - 0x3: Inst::IMUL(Gv,Ev,Ib); - 0x4: ins_Yb_Dx(); - 0x5: ins_Yz_Dx(); - 0x6: outs_Dx_Xb(); - 0x7: outs_Dx_Xz(); + 0x0: PUSH(Iz); + 0x1: IMUL(Gv,Ev,Iz); + 0x2: PUSH(Ib); + 0x3: IMUL(Gv,Ev,Ib); + 0x4: StringInst::INS(Yb,rD); + 0x5: StringInst::INS(Yz,rD); + 0x6: StringInst::OUTS(rD,Xb); + 0x7: StringInst::OUTS(rD,Xz); } - format Inst { - 0x0E: decode OPCODE_OP_BOTTOM3 { - 0x0: JO(Jb); - 0x1: JNO(Jb); - 0x2: JB(Jb); - 0x3: JNB(Jb); - 0x4: JZ(Jb); - 0x5: JNZ(Jb); - 0x6: JBE(Jb); - 0x7: JNBE(Jb); - } - 0x0F: decode OPCODE_OP_BOTTOM3 { - 0x0: JS(Jb); - 0x1: JNS(Jb); - 0x2: JP(Jb); - 0x3: JNP(Jb); - 0x4: JL(Jb); - 0x5: JNL(Jb); - 0x6: JLE(Jb); - 0x7: JNLE(Jb); - } + 0x0E: decode OPCODE_OP_BOTTOM3 { + 0x0: JO(Jb); + 0x1: JNO(Jb); + 0x2: JB(Jb); + 0x3: JNB(Jb); + 0x4: JZ(Jb); + 0x5: JNZ(Jb); + 0x6: JBE(Jb); + 0x7: JNBE(Jb); + } + 0x0F: decode OPCODE_OP_BOTTOM3 { + 0x0: JS(Jb); + 0x1: JNS(Jb); + 0x2: JP(Jb); + 0x3: JNP(Jb); + 0x4: JL(Jb); + 0x5: JNL(Jb); + 0x6: JLE(Jb); + 0x7: JNLE(Jb); } - format Inst { - 0x10: decode OPCODE_OP_BOTTOM3 { - //0x0: group1_Eb_Ib(); - 0x0: decode MODRM_REG { + 0x10: decode OPCODE_OP_BOTTOM3 { + //0x0: group1_Eb_Ib(); + 0x0: decode MODRM_REG { + 0x0: ADD(Eb,Ib); + 0x1: OR(Eb,Ib); + 0x2: ADC(Eb,Ib); + 0x3: SBB(Eb,Ib); + 0x4: AND(Eb,Ib); + 0x5: SUB(Eb,Ib); + 0x6: XOR(Eb,Ib); + 0x7: CMP(Eb,Ib); + } + //0x1: group1_Ev_Iz(); + 0x1: decode MODRM_REG { + 0x0: ADD(Ev,Iz); + 0x1: OR(Ev,Iz); + 0x2: ADC(Ev,Iz); + 0x3: SBB(Ev,Iz); + 0x4: AND(Ev,Iz); + 0x5: SUB(Ev,Iz); + 0x6: XOR(Ev,Iz); + 0x7: CMP(Ev,Iz); + } + 0x2: decode MODE_SUBMODE { + 0x0: UD2(); + //default: group1_Eb_Ib(); + default: decode MODRM_REG { 0x0: ADD(Eb,Ib); 0x1: OR(Eb,Ib); 0x2: ADC(Eb,Ib); @@ -248,313 +270,286 @@ 0x6: XOR(Eb,Ib); 0x7: CMP(Eb,Ib); } - //0x1: group1_Ev_Iz(); - 0x1: decode MODRM_REG { - 0x0: ADD(Ev,Iz); - 0x1: OR(Ev,Iz); - 0x2: ADC(Ev,Iz); - 0x3: SBB(Ev,Iz); - 0x4: AND(Ev,Iz); - 0x5: SUB(Ev,Iz); - 0x6: XOR(Ev,Iz); - 0x7: CMP(Ev,Iz); - } - 0x2: decode MODE_SUBMODE { - 0x0: UD2(); - //default: group1_Eb_Ib(); - default: decode MODRM_REG { - 0x0: ADD(Eb,Ib); - 0x1: OR(Eb,Ib); - 0x2: ADC(Eb,Ib); - 0x3: SBB(Eb,Ib); - 0x4: AND(Eb,Ib); - 0x5: SUB(Eb,Ib); - 0x6: XOR(Eb,Ib); - 0x7: CMP(Eb,Ib); - } - } - //0x3: group1_Ev_Ib(); - 0x3: decode MODRM_REG { - 0x0: ADD(Ev,Ib); - 0x1: OR(Ev,Ib); - 0x2: ADC(Ev,Ib); - 0x3: SBB(Ev,Ib); - 0x4: AND(Ev,Ib); - 0x5: SUB(Ev,Ib); - 0x6: XOR(Ev,Ib); - 0x7: CMP(Ev,Ib); - } - 0x4: TEST(Eb,Gb); - 0x5: TEST(Ev,Gv); - 0x6: XCHG(Eb,Gb); - 0x7: XCHG(Ev,Gv); } + //0x3: group1_Ev_Ib(); + 0x3: decode MODRM_REG { + 0x0: ADD(Ev,Ib); + 0x1: OR(Ev,Ib); + 0x2: ADC(Ev,Ib); + 0x3: SBB(Ev,Ib); + 0x4: AND(Ev,Ib); + 0x5: SUB(Ev,Ib); + 0x6: XOR(Ev,Ib); + 0x7: CMP(Ev,Ib); + } + 0x4: TEST(Eb,Gb); + 0x5: TEST(Ev,Gv); + 0x6: XCHG(Eb,Gb); + 0x7: XCHG(Ev,Gv); } 0x11: decode OPCODE_OP_BOTTOM3 { - 0x0: Inst::MOV(Eb,Gb); - 0x1: Inst::MOV(Ev,Gv); - 0x2: Inst::MOV(Gb,Eb); - 0x3: Inst::MOV(Gv,Ev); - 0x4: mov_MwRv_Sw(); //What to do with this one? - 0x5: Inst::LEA(Gv,M); - 0x6: mov_Sw_MwRv(); - 0x7: group10_Ev(); //Make sure this is Ev + 0x0: MOV(Eb,Gb); + 0x1: MOV(Ev,Gv); + 0x2: MOV(Gb,Eb); + 0x3: MOV(Gv,Ev); + 0x4: WarnUnimpl::mov_MwRv_Sw(); //What to do with this one? + 0x5: LEA(Gv,M); + 0x6: WarnUnimpl::mov_Sw_MwRv(); + //0x7: group10_Ev(); + 0x7: decode MODRM_REG { + 0x0: POP(Ev); + default: UD2(); + } } 0x12: decode OPCODE_OP_BOTTOM3 { - 0x0: Inst::NOP(); //XXX repe makes this a "pause" - default: Inst::XCHG(Bv,rAv); + 0x0: NOP(); //XXX repe makes this a "pause" + default: XCHG(Bv,rAv); } 0x13: decode OPCODE_OP_BOTTOM3 { - 0x0: Inst::CDQE(rAv); - 0x1: Inst::CQO(rAv,rDv); + 0x0: CDQE(rAv); + 0x1: CQO(rAv,rDv); 0x2: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: call_far_Ap(); + 0x0: UD2(); + default: WarnUnimpl::call_far_Ap(); } - 0x3: fwait(); //aka wait - 0x4: pushf_Fv(); - 0x5: popf_Fv(); + 0x3: WarnUnimpl::fwait(); //aka wait + 0x4: WarnUnimpl::pushf_Fv(); + 0x5: WarnUnimpl::popf_Fv(); //Both of these should be illegal only if CPUID.AHF64=0, //according to sandpile.org 0x6: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: sahf(); + 0x0: UD2(); + default: WarnUnimpl::sahf(); } 0x7: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: lahf(); + 0x0: UD2(); + default: WarnUnimpl::lahf(); } } - format Inst { - 0x14: decode OPCODE_OP_BOTTOM3 { - 0x0: MOV(rAb, Ob); - 0x1: MOV(rAv, Ov); - 0x2: MOV(Ob, rAb); - 0x3: MOV(Ov, rAv); - 0x4: StringInst::MOVS(Yb,Xb); - 0x5: StringInst::MOVS(Yv,Xv); - 0x6: StringTestInst::CMPS(Yb,Xb); - 0x7: StringTestInst::CMPS(Yv,Xv); - } - 0x15: decode OPCODE_OP_BOTTOM3 { - 0x0: TEST(rAb,Ib); - 0x1: TEST(rAv,Iz); - 0x2: StringInst::STOS(Yb); - 0x3: StringInst::STOS(Yv); - 0x4: StringInst::LODS(Xb); - 0x5: StringInst::LODS(Xv); - 0x6: StringTestInst::SCAS(Yb); - 0x7: StringTestInst::SCAS(Yv); - } - 0x16: MOV(Bb,Ib); - 0x17: MOV(Bv,Iv); - 0x18: decode OPCODE_OP_BOTTOM3 { - //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: SAL(Eb,Ib); - 0x5: SHR(Eb,Ib); - 0x6: 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: SAL(Ev,Ib); - 0x5: SHR(Ev,Ib); - 0x6: SAL(Ev,Ib); - 0x7: SAR(Ev,Ib); - } - 0x2: RET_NEAR(Iw); - 0x3: RET_NEAR(); - 0x4: decode MODE_SUBMODE { - 0x0: UD2(); - default: WarnUnimpl::les_Gz_Mp(); - } - 0x5: decode MODE_SUBMODE { - 0x0: UD2(); - default: WarnUnimpl::lds_Gz_Mp(); - } - //0x6: group12_Eb_Ib(); - 0x6: decode MODRM_REG { - 0x0: MOV(Eb,Ib); - default: UD2(); - } - //0x7: group12_Ev_Iz(); - 0x7: decode MODRM_REG { - 0x0: MOV(Ev,Iz); - default: UD2(); - } + 0x14: decode OPCODE_OP_BOTTOM3 { + 0x0: MOV(rAb, Ob); + 0x1: MOV(rAv, Ov); + 0x2: MOV(Ob, rAb); + 0x3: MOV(Ov, rAv); + 0x4: StringInst::MOVS(Yb,Xb); + 0x5: StringInst::MOVS(Yv,Xv); + 0x6: StringTestInst::CMPS(Yb,Xb); + 0x7: StringTestInst::CMPS(Yv,Xv); + } + 0x15: decode OPCODE_OP_BOTTOM3 { + 0x0: TEST(rAb,Ib); + 0x1: TEST(rAv,Iz); + 0x2: StringInst::STOS(Yb); + 0x3: StringInst::STOS(Yv); + 0x4: StringInst::LODS(Xb); + 0x5: StringInst::LODS(Xv); + 0x6: StringTestInst::SCAS(Yb); + 0x7: StringTestInst::SCAS(Yv); + } + 0x16: MOV(Bb,Ib); + 0x17: MOV(Bv,Iv); + 0x18: decode OPCODE_OP_BOTTOM3 { + //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: SAL(Eb,Ib); + 0x5: SHR(Eb,Ib); + 0x6: 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: SAL(Ev,Ib); + 0x5: SHR(Ev,Ib); + 0x6: SAL(Ev,Ib); + 0x7: SAR(Ev,Ib); + } + 0x2: RET_NEAR(Iw); + 0x3: RET_NEAR(); + 0x4: decode MODE_SUBMODE { + 0x0: UD2(); + default: WarnUnimpl::les_Gz_Mp(); + } + 0x5: decode MODE_SUBMODE { + 0x0: UD2(); + default: WarnUnimpl::lds_Gz_Mp(); + } + //0x6: group12_Eb_Ib(); + 0x6: decode MODRM_REG { + 0x0: MOV(Eb,Ib); + default: UD2(); + } + //0x7: group12_Ev_Iz(); + 0x7: decode MODRM_REG { + 0x0: MOV(Ev,Iz); + default: UD2(); } } - 0x19: decode OPCODE_OP_BOTTOM3 { - 0x0: enter_Iw_Ib(); - 0x1: Inst::LEAVE(); - 0x2: ret_far_Iw(); - 0x3: ret_far(); - 0x4: int3(); - 0x5: int_Ib(); - 0x6: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: into(); + format WarnUnimpl { + 0x19: decode OPCODE_OP_BOTTOM3 { + 0x0: enter_Iw_Ib(); + 0x1: Inst::LEAVE(); + 0x2: ret_far_Iw(); + 0x3: ret_far(); + 0x4: int3(); + 0x5: int_Ib(); + 0x6: decode MODE_SUBMODE { + 0x0: Inst::UD2(); + default: into(); + } + 0x7: iret(); } - 0x7: iret(); } 0x1A: decode OPCODE_OP_BOTTOM3 { - format Inst { - //0x0: group2_Eb_1(); - 0x0: decode MODRM_REG { - 0x0: ROL_1(Eb); - 0x1: ROR_1(Eb); - 0x2: RCL_1(Eb); - 0x3: RCR_1(Eb); - 0x4: SAL_1(Eb); - 0x5: SHR_1(Eb); - 0x6: SAL_1(Eb); - 0x7: SAR_1(Eb); - } - //0x1: group2_Ev_1(); - 0x1: decode MODRM_REG { - 0x0: ROL_1(Ev); - 0x1: ROR_1(Ev); - 0x2: RCL_1(Ev); - 0x3: RCR_1(Ev); - 0x4: SAL_1(Ev); - 0x5: SHR_1(Ev); - 0x6: SAL_1(Ev); - 0x7: SAR_1(Ev); - } - //0x2: group2_Eb_Cl(); - 0x2: decode MODRM_REG { - 0x0: ROL(Eb,rCb); - 0x1: ROR(Eb,rCb); - 0x2: RCL(Eb,rCb); - 0x3: RCR(Eb,rCb); - 0x4: SAL(Eb,rCb); - 0x5: SHR(Eb,rCb); - 0x6: SAL(Eb,rCb); - 0x7: SAR(Eb,rCb); - } - //The second operand should have size "b", but to have - //consistent register sizes it's "v". This shouldn't have - //any affect on functionality. - //0x3: group2_Ev_Cl(); - 0x3: decode MODRM_REG { - 0x0: ROL(Ev,rCv); - 0x1: ROR(Ev,rCv); - 0x2: RCL(Ev,rCv); - 0x3: RCR(Ev,rCv); - 0x4: SAL(Ev,rCv); - 0x5: SHR(Ev,rCv); - 0x6: SAL(Ev,rCv); - 0x7: SAR(Ev,rCv); - } + //0x0: group2_Eb_1(); + 0x0: decode MODRM_REG { + 0x0: ROL_1(Eb); + 0x1: ROR_1(Eb); + 0x2: RCL_1(Eb); + 0x3: RCR_1(Eb); + 0x4: SAL_1(Eb); + 0x5: SHR_1(Eb); + 0x6: SAL_1(Eb); + 0x7: SAR_1(Eb); + } + //0x1: group2_Ev_1(); + 0x1: decode MODRM_REG { + 0x0: ROL_1(Ev); + 0x1: ROR_1(Ev); + 0x2: RCL_1(Ev); + 0x3: RCR_1(Ev); + 0x4: SAL_1(Ev); + 0x5: SHR_1(Ev); + 0x6: SAL_1(Ev); + 0x7: SAR_1(Ev); + } + //0x2: group2_Eb_Cl(); + 0x2: decode MODRM_REG { + 0x0: ROL(Eb,rCb); + 0x1: ROR(Eb,rCb); + 0x2: RCL(Eb,rCb); + 0x3: RCR(Eb,rCb); + 0x4: SAL(Eb,rCb); + 0x5: SHR(Eb,rCb); + 0x6: SAL(Eb,rCb); + 0x7: SAR(Eb,rCb); + } + //The second operand should have size "b", but to have + //consistent register sizes it's "v". This shouldn't have + //any affect on functionality. + //0x3: group2_Ev_Cl(); + 0x3: decode MODRM_REG { + 0x0: ROL(Ev,rCv); + 0x1: ROR(Ev,rCv); + 0x2: RCL(Ev,rCv); + 0x3: RCR(Ev,rCv); + 0x4: SAL(Ev,rCv); + 0x5: SHR(Ev,rCv); + 0x6: SAL(Ev,rCv); + 0x7: SAR(Ev,rCv); } 0x4: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: aam_Ib(); + 0x0: UD2(); + default: WarnUnimpl::aam_Ib(); } 0x5: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: aad_Ib(); + 0x0: UD2(); + default: WarnUnimpl::aad_Ib(); } 0x6: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: salc(); + 0x0: UD2(); + default: SALC(rAb); } - 0x7: xlat(); + 0x7: XLAT(); } ##include "x87.isa" 0x1C: decode OPCODE_OP_BOTTOM3 { - 0x0: loopne_Jb(); - 0x1: loope_Jb(); - 0x2: loop_Jb(); - 0x3: jcxz_or_jecx_or_jrcx(); - 0x4: in_Al_Ib(); - 0x5: in_eAX_Ib(); - 0x6: out_Ib_Al(); - 0x7: out_Ib_eAX(); + 0x0: LOOPNE(Jb); + 0x1: LOOPE(Jb); + 0x2: LOOP(Jb); + 0x3: JRCX(Jb); + 0x4: IN(rAb,Ib); + 0x5: IN(rAv,Iv); + 0x6: OUT(Ib,rAb); + 0x7: OUT(Iv,rAv); } 0x1D: decode OPCODE_OP_BOTTOM3 { - 0x0: Inst::CALL_NEAR(Jz); - 0x1: Inst::JMP(Jz); + 0x0: CALL_NEAR(Jz); + 0x1: JMP(Jz); 0x2: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: jmp_far_Ap(); - } - 0x3: Inst::JMP(Jb); - 0x4: in_Al_Dx(); - 0x5: in_eAX_Dx(); - 0x6: out_Dx_Al(); - 0x7: out_Dx_eAX(); + 0x0: UD2(); + default: WarnUnimpl::jmp_far_Ap(); + } + 0x3: JMP(Jb); + 0x4: IN(rAb,rD); + 0x5: IN(rAv,rD); + 0x6: OUT(rD,rAb); + 0x7: OUT(rD,rAv); } 0x1E: decode OPCODE_OP_BOTTOM3 { 0x0: M5InternalError::error( {{"Tried to execute the lock prefix!"}}); - 0x1: int1(); + 0x1: WarnUnimpl::int1(); 0x2: M5InternalError::error( {{"Tried to execute the repne prefix!"}}); 0x3: M5InternalError::error( {{"Tried to execute the rep/repe prefix!"}}); - 0x4: hlt(); - 0x5: cmc(); - format Inst { - //0x6: group3_Eb(); - 0x6: decode MODRM_REG { - 0x0: TEST(Eb,Iz); - 0x1: TEST(Eb,Iz); - 0x2: NOT(Eb); - 0x3: NEG(Eb); - 0x4: MUL_B(Eb); - 0x5: IMUL_B(Eb); - //This should be Eb, but it access the entire word value ax. - 0x6: DIV_B(Ew); - 0x7: IDIV(Eb); - } - //0x7: group3_Ev(); - 0x7: decode MODRM_REG { - 0x0: TEST(Ev,Iz); - 0x1: TEST(Ev,Iz); - 0x2: NOT(Ev); - 0x3: NEG(Ev); - 0x4: MUL(Ev); - 0x5: IMUL(Ev); - 0x6: DIV(Ev); - 0x7: IDIV(Ev); - } + 0x4: WarnUnimpl::hlt(); + 0x5: CMC(); + //0x6: group3_Eb(); + 0x6: decode MODRM_REG { + 0x0: TEST(Eb,Iz); + 0x1: TEST(Eb,Iz); + 0x2: NOT(Eb); + 0x3: NEG(Eb); + 0x4: MUL_B(Eb); + 0x5: IMUL_B(Eb); + //This should be Eb, but it access the entire word value ax. + 0x6: DIV_B(Ew); + 0x7: IDIV(Eb); + } + //0x7: group3_Ev(); + 0x7: decode MODRM_REG { + 0x0: TEST(Ev,Iz); + 0x1: TEST(Ev,Iz); + 0x2: NOT(Ev); + 0x3: NEG(Ev); + 0x4: MUL(Ev); + 0x5: IMUL(Ev); + 0x6: DIV(Ev); + 0x7: IDIV(Ev); } } 0x1F: decode OPCODE_OP_BOTTOM3 { - format Inst { - 0x0: CLC(); - 0x1: STC(); - 0x2: WarnUnimpl::cli(); - 0x3: WarnUnimpl::sti(); - 0x4: CLD(); - 0x5: STD(); - //0x6: group4(); - 0x6: decode MODRM_REG { - 0x0: INC(Eb); - 0x1: DEC(Eb); - default: UD2(); - } - //0x7: group5(); - 0x7: decode MODRM_REG { - 0x0: INC(Ev); - 0x1: DEC(Ev); - 0x2: CALL_NEAR(Ev); - 0x3: WarnUnimpl::call_far_Mp(); - 0x4: JMP(Ev); - 0x5: WarnUnimpl::jmp_far_Mp(); - 0x6: PUSH(Ev); - 0x7: UD2(); - } + 0x0: CLC(); + 0x1: STC(); + 0x2: WarnUnimpl::cli(); + 0x3: WarnUnimpl::sti(); + 0x4: CLD(); + 0x5: STD(); + //0x6: group4(); + 0x6: decode MODRM_REG { + 0x0: INC(Eb); + 0x1: DEC(Eb); + default: UD2(); + } + //0x7: group5(); + 0x7: decode MODRM_REG { + 0x0: INC(Ev); + 0x1: DEC(Ev); + 0x2: CALL_NEAR(Ev); + 0x3: WarnUnimpl::call_far_Mp(); + 0x4: JMP(Ev); + 0x5: WarnUnimpl::jmp_far_Mp(); + 0x6: PUSH(Ev); + 0x7: UD2(); } } } diff --git a/src/arch/x86/isa/decoder/x87.isa b/src/arch/x86/isa/decoder/x87.isa index 667a8a66e..9a6473141 100644 --- a/src/arch/x86/isa/decoder/x87.isa +++ b/src/arch/x86/isa/decoder/x87.isa @@ -53,294 +53,296 @@ // // 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(); +format WarnUnimpl { + 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(); } - 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(); + 0x2: decode MODRM_MOD { + 0x3: decode MODRM_RM { + 0x0: fnop(); + default: Inst::UD2(); + } + default: fst(); } - 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_Mw(); - } - 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_Mw(); - } - } - //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(); + 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_Mw(); + } + 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_Mw(); } - 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(); + //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(); + } } - 0x4: decode MODRM_MOD { - 0x3: decode MODRM_RM { - 0x2: fnclex(); - 0x3: fninit(); + //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(); } - 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: Inst::FLD(Mq); - } - 0x1: decode MODRM_MOD { - 0x3: Inst::UD2(); - default: fisttp(); - } - 0x2: Inst::FST(Mq); - 0x3: Inst::FSTP(Mq); - 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(); + 0x5: decode MODRM_MOD { + 0x3: fucomi(); + default: fld(); + } + 0x6: decode MODRM_MOD { + 0x3: fcomi(); 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(); + 0x7: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fstp(); + } } - 0x3: decode MODRM_MOD { - 0x3: Inst::UD2(); - default: fistp(); + //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(); + } } - 0x4: decode MODRM_MOD { - 0x3: decode MODRM_RM { - 0x0: fnstsw(); + //0x5: esc5(); + 0x5: decode MODRM_REG { + 0x0: decode MODRM_MOD { + 0x3: ffree(); + default: Inst::FLD(Mq); + } + 0x1: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fisttp(); + } + 0x2: Inst::FST(Mq); + 0x3: Inst::FSTP(Mq); + 0x4: decode MODRM_MOD { + 0x3: fucom(); + default: frstor(); + } + 0x5: decode MODRM_MOD { + 0x3: fucomp(); default: Inst::UD2(); } - default: fbld(); - } - 0x5: decode MODRM_MOD { - 0x3: fucomip(); - default: fild(); + 0x6: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fnsave(); + } + 0x7: decode MODRM_MOD { + 0x3: Inst::UD2(); + default: fnstsw(); + } } - 0x6: decode MODRM_MOD { - 0x3: fcomip(); - default: fbstp(); + //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: decode MODRM_MOD { - 0x3: Inst::UD2(); - default: fistp(); + //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(); + } } } } diff --git a/src/arch/x86/isa/formats/string.isa b/src/arch/x86/isa/formats/string.isa index b1d3c4bbe..cb3ebc496 100644 --- a/src/arch/x86/isa/formats/string.isa +++ b/src/arch/x86/isa/formats/string.isa @@ -103,7 +103,7 @@ def format StringInst(*opTypeSet) {{ %s } else if (LEGACY_REPNE) { // The repne prefix is illegal - return new MicroFault(machInst, "illprefix", new InvalidOpcode); + return new MicroFault(machInst, "illprefix", new InvalidOpcode, 0); } else { %s } diff --git a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bounds.py b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bounds.py index 4b6cc8f71..2df5cf746 100644 --- a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bounds.py +++ b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bounds.py @@ -53,8 +53,17 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class BOUND(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' +def macroop BOUND_R_M { + ld t1, seg, sib, disp, dataSize="env.dataSize * 2" + srli t2, t1, "env.dataSize * 8" + sub t1, t1, reg, flags=(ECF,) + fault "new BoundRange", flags=(CECF,) + sub t2, reg, t2, flags=(ECF,) + fault "new BoundRange", flags=(CECF,) +}; + +def macroop BOUND_R_P { + fault "new UnimpInstFault" +}; +''' diff --git a/src/arch/x86/isa/insts/general_purpose/compare_and_test/set_byte_on_condition.py b/src/arch/x86/isa/insts/general_purpose/compare_and_test/set_byte_on_condition.py index 81091905c..fab42dffd 100644 --- a/src/arch/x86/isa/insts/general_purpose/compare_and_test/set_byte_on_condition.py +++ b/src/arch/x86/isa/insts/general_purpose/compare_and_test/set_byte_on_condition.py @@ -54,6 +54,11 @@ # Authors: Gabe Black microcode = ''' +def macroop SALC_R +{ + sbb reg, reg, reg, dataSize=1 +}; + def macroop SETZ_R { movi reg, reg, 1, flags=(CZF,) diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/conditional_jump.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/conditional_jump.py index b04ca97d6..c2856e630 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/conditional_jump.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/conditional_jump.py @@ -213,4 +213,11 @@ def macroop JNO_I limm t2, imm wrip t1, t2, flags=(nCOF,) }; + +def macroop JRCX_I +{ + rdip t1 + add t0, t0, rcx, flags=(EZF,), dataSize=asz + wripi t1, imm, flags=(CEZF,) +}; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/loop.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/loop.py index d742f217f..c5674db7f 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/loop.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/loop.py @@ -53,8 +53,22 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class LOOPcc(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' +def macroop LOOP_I { + rdip t1 + subi rcx, rcx, 1, flags=(EZF,), dataSize=asz + wripi t1, imm, flags=(nCEZF,) +}; + +def macroop LOOPNE_I { + rdip t1 + subi rcx, rcx, 1, flags=(EZF,), dataSize=asz + wripi t1, imm, flags=(CSTRnZnEZF,) +}; + +def macroop LOOPE_I { + rdip t1 + subi rcx, rcx, 1, flags=(EZF,), dataSize=asz + wripi t1, imm, flags=(CSTRZnEZF,) +}; +''' diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py index bb286b976..c2ccb9d19 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py +++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py @@ -53,8 +53,12 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class XLAT(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' +def macroop XLAT { + zext t1, rax, 8 + # Here, t1 can be used directly. The value of al is supposed to be treated + # as unsigned. Since we zero extended it from 8 bits above and the address + # size has to be at least 16 bits, t1 will not be sign extended. + ld rax, seg, [1, rbx, t1], dataSize=1 +}; +''' diff --git a/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py b/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py index f9aa9d6e4..c01a11035 100644 --- a/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py +++ b/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py @@ -53,10 +53,28 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class IN(Inst): -# "GenFault ${new UnimpInstFault}" -# class OUT(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' + def macroop IN_R_I { + .adjust_imm trimImm(8) + limm t1, "IntAddrPrefixIO" + ld reg, intseg, [1, t1, t0], imm, addressSize=2 + }; + + def macroop IN_R_R { + limm t1, "IntAddrPrefixIO" + zext t2, regm, 16, dataSize=2 + ld reg, intseg, [1, t1, t2], addressSize=8 + }; + + def macroop OUT_I_R { + .adjust_imm trimImm(8) + limm t1, "IntAddrPrefixIO" + st reg, intseg, [1, t1, t0], imm, addressSize=8 + }; + + def macroop OUT_R_R { + limm t1, "IntAddrPrefixIO" + zext t2, reg, 16, dataSize=2 + st regm, intseg, [1, t1, t2], addressSize=8 + }; +''' diff --git a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py index a35ba772f..a8acbbc39 100644 --- a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py +++ b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py @@ -53,26 +53,76 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class INS(Inst): -# "GenFault ${new UnimpInstFault}" -# class INSB(Inst): -# "GenFault ${new UnimpInstFault}" -# class INSW(Inst): -# "GenFault ${new UnimpInstFault}" -# class INSD(Inst): -# "GenFault ${new UnimpInstFault}" -# class INSQ(Inst): -# "GenFault ${new UnimpInstFault}" -# class OUTS(Inst): -# "GenFault ${new UnimpInstFault}" -# class OUTSB(Inst): -# "GenFault ${new UnimpInstFault}" -# class OUTSW(Inst): -# "GenFault ${new UnimpInstFault}" -# class OUTSD(Inst): -# "GenFault ${new UnimpInstFault}" -# class OUTSQ(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' +def macroop INS_M_R { + # Find the constant we need to either add or subtract from rdi + ruflag t0, 10 + movi t3, t3, dsz, flags=(CEZF,), dataSize=asz + subi t4, t0, dsz, dataSize=asz + mov t3, t3, t4, flags=(nCEZF,), dataSize=asz + + limm t1, "IntAddrPrefixIO" + zext t2, reg, 16, dataSize=2 + + ld t6, intseg, [1, t1, t2], addressSize=8 + st t6, es, [1, t0, rdi] + + add rdi, rdi, t3, dataSize=asz +}; + +def macroop INS_E_M_R { + # Find the constant we need to either add or subtract from rdi + ruflag t0, 10 + movi t3, t3, dsz, flags=(CEZF,), dataSize=asz + subi t4, t0, dsz, dataSize=asz + mov t3, t3, t4, flags=(nCEZF,), dataSize=asz + + limm t1, "IntAddrPrefixIO" + zext t2, reg, 16, dataSize=2 + +topOfLoop: + ld t6, intseg, [1, t1, t2], addressSize=8 + st t6, es, [1, t0, rdi] + + subi rcx, rcx, 1, flags=(EZF,), dataSize=asz + add rdi, rdi, t3, dataSize=asz + bri t0, label("topOfLoop"), flags=(nCEZF,) + fault "NoFault" +}; + +def macroop OUTS_R_M { + # Find the constant we need to either add or subtract from rdi + ruflag t0, 10 + movi t3, t3, dsz, flags=(CEZF,), dataSize=asz + subi t4, t0, dsz, dataSize=asz + mov t3, t3, t4, flags=(nCEZF,), dataSize=asz + + limm t1, "IntAddrPrefixIO" + zext t2, reg, 16, dataSize=2 + + ld t6, ds, [1, t0, rsi] + st t6, intseg, [1, t1, t2], addressSize=8 + + add rsi, rsi, t3, dataSize=asz +}; + +def macroop OUTS_E_R_M { + # Find the constant we need to either add or subtract from rdi + ruflag t0, 10 + movi t3, t3, dsz, flags=(CEZF,), dataSize=asz + subi t4, t0, dsz, dataSize=asz + mov t3, t3, t4, flags=(nCEZF,), dataSize=asz + + limm t1, "IntAddrPrefixIO" + zext t2, reg, 16, dataSize=2 + +topOfLoop: + ld t6, ds, [1, t0, rsi] + st t6, intseg, [1, t1, t2], addressSize=8 + + subi rcx, rcx, 1, flags=(EZF,), dataSize=asz + add rsi, rsi, t3, dataSize=asz + bri t0, label("topOfLoop"), flags=(nCEZF,) + fault "NoFault" +}; +''' diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa index c9c33f981..4818b926c 100644 --- a/src/arch/x86/isa/macroop.isa +++ b/src/arch/x86/isa/macroop.isa @@ -142,6 +142,8 @@ def template MacroConstructor {{ : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s) { %(adjust_env)s; + %(adjust_imm)s; + %(adjust_disp)s; %(do_modrm)s; %(constructor)s; //alloc_microops is the code that sets up the microops @@ -159,14 +161,30 @@ let {{ self.microops.append(microop) def setAdjustEnv(self, val): self.adjust_env = val + def adjustImm(self, val): + self.adjust_imm += val + def adjustDisp(self, val): + self.adjust_disp += val def __init__(self, name): super(X86Macroop, self).__init__(name) self.directives = { - "adjust_env" : self.setAdjustEnv + "adjust_env" : self.setAdjustEnv, + "adjust_imm" : self.adjustImm, + "adjust_disp" : self.adjustDisp } self.declared = False self.adjust_env = "" self.doModRM = "" + self.adjust_imm = ''' + uint64_t adjustedImm = IMMEDIATE; + //This is to pacify gcc in case the immediate isn't used. + adjustedImm = adjustedImm; + ''' + self.adjust_disp = ''' + uint64_t adjustedDisp = DISPLACEMENT; + //This is to pacify gcc in case the displacement isn't used. + adjustedDisp = adjustedDisp; + ''' def getAllocator(self, env): return "new X86Macroop::%s(machInst, %s)" % (self.name, env.getAllocator()) def getDeclaration(self): @@ -198,6 +216,8 @@ let {{ {"code" : "", "num_microops" : numMicroops, "alloc_microops" : allocMicroops, "adjust_env" : self.adjust_env, + "adjust_imm" : self.adjust_imm, + "adjust_disp" : self.adjust_disp, "do_modrm" : self.doModRM}) return MacroConstructor.subst(iop); }}; diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 50135e30c..0c43d4c13 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -88,8 +88,8 @@ let {{ "regm" : "env.regm", "xmmlm" : "FLOATREG_XMM_LOW(env.regm)", "xmmhm" : "FLOATREG_XMM_HIGH(env.regm)", - "imm" : "IMMEDIATE", - "disp" : "DISPLACEMENT", + "imm" : "adjustedImm", + "disp" : "adjustedDisp", "seg" : "env.seg", "scale" : "env.scale", "index" : "env.index", @@ -135,6 +135,11 @@ let {{ env.dataSize = 8; ''' + def trimImm(width): + return "adjustedImm = adjustedImm & mask(%s);" % width + + assembler.symbols["trimImm"] = trimImm + def labeler(labelStr): return "label_%s" % labelStr diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index ab113a699..892c44487 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -835,7 +835,7 @@ let {{ ''' class Wrip(WrRegOp, CondRegOp): - code = 'RIP = psrc1 + op2' + code = 'RIP = psrc1 + sop2' else_code="RIP = RIP;" class Br(WrRegOp, CondRegOp): diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa index 5c9e8dda9..ca4a6dc57 100644 --- a/src/arch/x86/isa/microops/specop.isa +++ b/src/arch/x86/isa/microops/specop.isa @@ -60,57 +60,106 @@ ////////////////////////////////////////////////////////////////////////// output header {{ - class MicroFault : public X86ISA::X86MicroopBase + class MicroFaultBase : public X86ISA::X86MicroopBase { protected: Fault fault; - void buildMe(); + uint8_t cc; public: - MicroFault(ExtMachInst _machInst, const char * instMnem, + MicroFaultBase(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - Fault _fault); - - MicroFault(ExtMachInst _machInst, const char * instMnem, - Fault _fault); + Fault _fault, uint8_t _cc); - %(BasicExecDeclare)s + MicroFaultBase(ExtMachInst _machInst, const char * instMnem, + Fault _fault, uint8_t _cc); std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; }}; -output decoder {{ - Fault MicroFault::execute(%(CPU_exec_context)s *xc, +def template MicroFaultDeclare {{ + class %(class_name)s : public %(base_class)s + { + private: + void buildMe(); + public: + %(class_name)s(ExtMachInst _machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + Fault _fault, uint8_t _cc); + + %(class_name)s(ExtMachInst _machInst, const char * instMnem, + Fault _fault, uint8_t _cc); + + %(BasicExecDeclare)s + }; +}}; + +def template MicroFaultExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - //Return the fault we were constructed with - return fault; + %(op_decl)s; + %(op_rd)s; + if (%(cond_test)s) { + //Return the fault we were constructed with + return fault; + } else { + return NoFault; + } } }}; output decoder {{ - inline MicroFault::MicroFault( - ExtMachInst machInst, const char * instMnem, Fault _fault) : + inline MicroFaultBase::MicroFaultBase( + ExtMachInst machInst, const char * instMnem, + Fault _fault, uint8_t _cc) : X86MicroopBase(machInst, "fault", instMnem, - false, false, false, false, No_OpClass), fault(_fault) + false, false, false, false, No_OpClass), + fault(_fault), cc(_cc) { } - inline MicroFault::MicroFault( + inline MicroFaultBase::MicroFaultBase( ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - Fault _fault) : + Fault _fault, uint8_t _cc) : X86MicroopBase(machInst, "fault", instMnem, isMicro, isDelayed, isFirst, isLast, No_OpClass), - fault(_fault) + fault(_fault), cc(_cc) { } }}; +def template MicroFaultConstructor {{ + + inline void %(class_name)s::buildMe() + { + %(constructor)s; + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + Fault _fault, uint8_t _cc) : + %(base_class)s(machInst, instMnem, _fault, _cc) + { + buildMe(); + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + Fault _fault, uint8_t _cc) : + %(base_class)s(machInst, instMnem, + isMicro, isDelayed, isFirst, isLast, _fault, _cc) + { + buildMe(); + } +}}; + output decoder {{ - std::string MicroFault::generateDisassembly(Addr pc, + std::string MicroFaultBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream response; @@ -127,14 +176,37 @@ output decoder {{ let {{ class Fault(X86Microop): - def __init__(self, fault): + className = "MicroFault" + def __init__(self, fault, flags=None): self.fault = fault + if flags: + if not isinstance(flags, (list, tuple)): + raise Exception, "flags must be a list or tuple of flags" + self.cond = " | ".join(flags) + self.className += "Flags" + else: + self.cond = "0" def getAllocator(self, *microFlags): - allocator = '''new MicroFault(machInst, mnemonic - %(flags)s, %(fault)s)''' % { + allocator = '''new %(class_name)s(machInst, mnemonic + %(flags)s, %(fault)s, %(cc)s)''' % { + "class_name" : self.className, "flags" : self.microFlagsText(microFlags), - "fault" : self.fault} + "fault" : self.fault, + "cc" : self.cond} return allocator + + iop = InstObjParams("fault", "MicroFault", "MicroFaultBase", + {"code": "", + "cond_test": "checkCondition(ccFlagBits, cc)"}) + exec_output = MicroFaultExecute.subst(iop) + header_output = MicroFaultDeclare.subst(iop) + decoder_output = MicroFaultConstructor.subst(iop) + iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase", + {"code": "", + "cond_test": "true"}) + exec_output += MicroFaultExecute.subst(iop) + header_output += MicroFaultDeclare.subst(iop) + decoder_output += MicroFaultConstructor.subst(iop) microopClasses["fault"] = Fault }}; diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh index beb1898ce..dd9258db0 100644 --- a/src/arch/x86/x86_traits.hh +++ b/src/arch/x86/x86_traits.hh @@ -86,6 +86,7 @@ namespace X86ISA const Addr IntAddrPrefixMask = ULL(0xffffffff00000000); const Addr IntAddrPrefixCPUID = ULL(0x100000000); const Addr IntAddrPrefixMSR = ULL(0x200000000); + const Addr IntAddrPrefixIO = ULL(0x300000000); } #endif //__ARCH_X86_X86TRAITS_HH__ |