summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa671
-rw-r--r--src/arch/x86/isa/decoder/x87.isa546
-rw-r--r--src/arch/x86/isa/formats/string.isa2
-rw-r--r--src/arch/x86/isa/insts/general_purpose/compare_and_test/bounds.py19
-rw-r--r--src/arch/x86/isa/insts/general_purpose/compare_and_test/set_byte_on_condition.py5
-rw-r--r--src/arch/x86/isa/insts/general_purpose/control_transfer/conditional_jump.py7
-rw-r--r--src/arch/x86/isa/insts/general_purpose/control_transfer/loop.py24
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py14
-rw-r--r--src/arch/x86/isa/insts/general_purpose/input_output/general_io.py32
-rw-r--r--src/arch/x86/isa/insts/general_purpose/input_output/string_io.py96
-rw-r--r--src/arch/x86/isa/macroop.isa22
-rw-r--r--src/arch/x86/isa/microasm.isa9
-rw-r--r--src/arch/x86/isa/microops/regop.isa2
-rw-r--r--src/arch/x86/isa/microops/specop.isa118
-rw-r--r--src/arch/x86/x86_traits.hh1
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__