diff options
author | Korey Sewell <ksewell@umich.edu> | 2007-11-15 00:14:20 -0500 |
---|---|---|
committer | Korey Sewell <ksewell@umich.edu> | 2007-11-15 00:14:20 -0500 |
commit | 375ddf8d25c3d81a77bd5dd7b70f84a0dbe48fe8 (patch) | |
tree | 525cf56502718b69fb7f0e78162a8d5e63256489 /src/arch/x86/isa | |
parent | 2820a448e2bcb861d099b1256087004462b78895 (diff) | |
parent | 7c8e4ca3a3b66becbc3e4e7b5e106f5c44b09b6f (diff) | |
download | gem5-375ddf8d25c3d81a77bd5dd7b70f84a0dbe48fe8.tar.xz |
branch merge
--HG--
extra : convert_revision : 1c56f3c6f2c50d642d2de5ddde83a55234455cec
Diffstat (limited to 'src/arch/x86/isa')
14 files changed, 563 insertions, 67 deletions
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 0482fdf23..f3485bc4e 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -61,8 +61,62 @@ 0x0F: decode OPCODE_OP_TOP5 { format WarnUnimpl { 0x00: decode OPCODE_OP_BOTTOM3 { - 0x00: group6(); - 0x01: group7(); + //0x00: group6(); + 0x00: decode MODRM_REG { + 0x0: sldt_Mw_or_Rv(); + 0x1: str_Mw_or_Rv(); + 0x2: lldt_Mw_or_Rv(); + 0x3: ltr_Mw_or_Rv(); + 0x4: verr_Mw_or_Rv(); + 0x5: verw_Mw_or_Rv(); + //0x6: jmpe_Ev(); // IA-64 + default: Inst::UD2(); + } + //0x01: group7(); // Ugly, ugly, ugly... + 0x01: decode MODRM_MOD { + 0x3: decode MODRM_REG { + 0x0: decode MODRM_RM { + 0x1: vmcall(); + 0x2: vmlaunch(); + 0x3: vmresume(); + 0x4: vmxoff(); + default: Inst::UD2(); + } + 0x1: decode MODRM_RM { + 0x0: monitor(); + 0x1: mwait(); + default: Inst::UD2(); + } + 0x3: decode MODRM_RM { + 0x0: vmrun(); + 0x1: vmmcall(); + 0x2: vmload(); + 0x3: vmsave(); + 0x4: stgi(); + 0x5: clgi(); + 0x6: skinit(); + 0x7: invlpga(); + } + 0x4: smsw_Rv(); + 0x6: lmsw_Rv(); + 0x7: decode MODRM_RM { + 0x0: swapgs(); + 0x1: rdtscp(); + default: Inst::UD2(); + } + default: Inst::UD2(); + } + default: decode MODRM_REG { + 0x0: sgdt_Ms(); + 0x1: sidt_Ms(); + 0x2: lgdt_Ms(); + 0x3: lidt_Ms(); + 0x4: smsw_Mw(); + 0x6: lmsw_Mw(); + 0x7: invlpg_M(); + default: Inst::UD2(); + } + } 0x02: lar_Gv_Ew(); 0x03: lsl_Gv_Ew(); //sandpile.org doesn't seem to know what this is... ? @@ -148,7 +202,7 @@ 0x0: decode OPCODE_OP_BOTTOM3 { 0x0: mov_Rd_Cd(); 0x1: mov_Rd_Dd(); - 0x2: mov_Cd_Rd(); + 0x2: Inst::MOV(Cd,Rd); 0x3: mov_Dd_Rd(); 0x4: mov_Rd_Td(); 0x6: mov_Td_Rd(); @@ -397,9 +451,58 @@ // no prefix 0x0: decode OPCODE_OP_BOTTOM3 { 0x0: pshufw_Pq_Qq_Ib(); - 0x1: group13_pshimw(); - 0x2: group14_pshimd(); - 0x3: group15_pshimq(); + //0x1: group13_pshimw(); + 0x1: decode MODRM_REG { + 0x2: decode LEGACY_OP { + 0x0: psrlw_PRq_Ib(); + 0x1: psrlw_VRo_Ib(); + } + 0x4: decode LEGACY_OP { + 0x0: psraw_PRq_Ib(); + 0x1: psraw_VRo_Ib(); + } + 0x6: decode LEGACY_OP { + 0x0: psllw_PRq_Ib(); + 0x1: psllw_VRo_Ib(); + } + default: Inst::UD2(); + } + //0x2: group14_pshimd(); + 0x2: decode MODRM_REG { + 0x2: decode LEGACY_OP { + 0x0: psrld_PRq_Ib(); + 0x1: psrld_VRo_Ib(); + } + 0x4: decode LEGACY_OP { + 0x0: psrad_PRq_Ib(); + 0x1: psrad_VRo_Ib(); + } + 0x6: decode LEGACY_OP { + 0x0: pslld_PRq_Ib(); + 0x1: pslld_VRo_Ib(); + } + default: Inst::UD2(); + } + //0x3: group15_pshimq(); + 0x3: decode MODRM_REG { + 0x2: decode LEGACY_OP { + 0x0: psrlq_PRq_Ib(); + 0x1: psrlq_VRo_Ib(); + } + 0x3: decode LEGACY_OP { + 0x0: Inst::UD2(); + 0x1: psrldq_VRo_Ib(); + } + 0x6: decode LEGACY_OP { + 0x0: psllq_PRq_Ib(); + 0x1: psllq_VRo_Ib(); + } + 0x7: decode LEGACY_OP { + 0x0: Inst::UD2(); + 0x1: pslldq_VRo_Ib(); + } + default: Inst::UD2(); + } 0x4: pcmpeqb_Pq_Qq(); 0x5: pcmpeqw_Pq_Qq(); 0x6: pcmpeqd_Pq_Qq(); @@ -413,9 +516,58 @@ // operand size (0x66) 0x1: decode OPCODE_OP_BOTTOM3 { 0x0: pshufd_Vo_Wo_Ib(); - 0x1: group13_pshimw(); - 0x2: group14_pshimd(); - 0x3: group15_pshimq_dq(); + //0x1: group13_pshimw(); + 0x1: decode MODRM_REG { + 0x2: decode LEGACY_OP { + 0x0: psrlw_PRq_Ib(); + 0x1: psrlw_VRo_Ib(); + } + 0x4: decode LEGACY_OP { + 0x0: psraw_PRq_Ib(); + 0x1: psraw_VRo_Ib(); + } + 0x6: decode LEGACY_OP { + 0x0: psllw_PRq_Ib(); + 0x1: psllw_VRo_Ib(); + } + default: Inst::UD2(); + } + //0x2: group14_pshimd(); + 0x2: decode MODRM_REG { + 0x2: decode LEGACY_OP { + 0x0: psrld_PRq_Ib(); + 0x1: psrld_VRo_Ib(); + } + 0x4: decode LEGACY_OP { + 0x0: psrad_PRq_Ib(); + 0x1: psrad_VRo_Ib(); + } + 0x6: decode LEGACY_OP { + 0x0: pslld_PRq_Ib(); + 0x1: pslld_VRo_Ib(); + } + default: Inst::UD2(); + } + //0x3: group15_pshimq(); + 0x3: decode MODRM_REG { + 0x2: decode LEGACY_OP { + 0x0: psrlq_PRq_Ib(); + 0x1: psrlq_VRo_Ib(); + } + 0x3: decode LEGACY_OP { + 0x0: Inst::UD2(); + 0x1: psrldq_VRo_Ib(); + } + 0x6: decode LEGACY_OP { + 0x0: psllq_PRq_Ib(); + 0x1: psllq_VRo_Ib(); + } + 0x7: decode LEGACY_OP { + 0x0: Inst::UD2(); + 0x1: pslldq_VRo_Ib(); + } + default: Inst::UD2(); + } 0x4: pcmpeqb_Vo_Wo(); 0x5: pcmpeqw_Vo_Wo(); 0x6: pcmpeqd_Vo_Wo(); @@ -505,7 +657,7 @@ 0x0: push_fs(); 0x1: pop_fs(); 0x2: Inst::CPUID(rAd); - 0x3: bt_Ev_Gv(); + 0x3: Inst::BT(Ev,Gv); 0x4: shld_Ev_Gv_Ib(); 0x5: shld_Ev_Gv_rCl(); 0x6: xbts_and_cmpxchg(); @@ -515,17 +667,31 @@ 0x0: push_gs(); 0x1: pop_gs(); 0x2: rsm_smm(); - 0x3: bts_Ev_Gv(); + 0x3: Inst::BTS(Ev,Gv); 0x4: shrd_Ev_Gv_Ib(); 0x5: shrd_Ev_Gv_rCl(); - 0x6: group16(); + //0x6: group16(); + 0x6: decode MODRM_MOD { + 0x3: decode MODRM_REG { + 0x5: lfence(); + 0x6: mfence(); + 0x7: sfence(); + default: Inst::UD2(); + } + default: decode MODRM_REG { + 0x0: fxsave(); + 0x1: fxrstor(); + 0x7: clflush(); + default: Inst::UD2(); + } + } 0x7: Inst::IMUL(Gv,Ev); } 0x16: decode OPCODE_OP_BOTTOM3 { 0x0: Inst::CMPXCHG(Eb,Gb); 0x1: Inst::CMPXCHG(Ev,Gv); 0x2: lss_Gz_Mp(); - 0x3: btr_Ev_Gv(); + 0x3: Inst::BTR(Ev,Gv); 0x4: lfs_Gz_Mp(); 0x5: lgs_Gz_Mp(); //The size of the second operand in these instructions should @@ -536,9 +702,19 @@ } 0x17: decode OPCODE_OP_BOTTOM3 { 0x0: jmpe_Jz(); // IA-64? - 0x1: group11_UD2(); - 0x2: group8_Ev_Ib(); - 0x3: btc_Ev_Gv(); + format Inst { + //0x1: group11_UD2(); + 0x1: UD2(); + //0x2: group8_Ev_Ib(); + 0x2: decode MODRM_REG { + 0x4: BT(Ev,Ib); + 0x5: BTS(Ev,Ib); + 0x6: BTR(Ev,Ib); + 0x7: BTC(Ev,Ib); + default: UD2(); + } + 0x3: BTC(Ev,Gv); + } 0x4: bsf_Gv_Ev(); 0x5: bsr_Gv_Ev(); //The size of the second operand in these instructions should @@ -550,7 +726,19 @@ 0x18: decode OPCODE_OP_BOTTOM3 { 0x0: xadd_Eb_Gb(); 0x1: xadd_Ev_Gv(); - 0x7: group9(); + //0x7: group9(); + 0x7: decode MODRM_REG { + 0x1: cmpxchg_Mq(); + 0x6: decode LEGACY_OP { + 0x1: vmclear_Mq(); + default: decode LEGACY_REP { + 0x1: vmxon_Mq(); + 0x0: vmptrld_Mq(); + } + } + 0x7: vmptrst_Mq(); + default: Inst::UD2(); + } default: decode LEGACY_DECODEVAL { // no prefix 0x0: decode OPCODE_OP_BOTTOM3 { diff --git a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_test.py b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_test.py index e950f008a..883ec4411 100644 --- a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_test.py +++ b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_test.py @@ -53,14 +53,242 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class BT(Inst): -# "GenFault ${new UnimpInstFault}" -# class BTC(Inst): -# "GenFault ${new UnimpInstFault}" -# class BTR(Inst): -# "GenFault ${new UnimpInstFault}" -# class BTS(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' +def macroop BT_R_I { + sexti t0, reg, imm, flags=(CF,) +}; + +def macroop BT_M_I { + limm t1, imm + # This fudges just a tiny bit, but it's reasonable to expect the + # microcode generation logic to have the log of the various sizes + # floating around as well. + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + add t2, t2, base + ld t1, seg, [scale, index, t2], disp + sexti t0, t1, imm, flags=(CF,) +}; + +def macroop BT_P_I { + rdip t7 + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + ld t1, seg, [1, t2, t7] + sexti t0, t1, imm, flags=(CF,) +}; + +def macroop BT_R_R { + sext t0, reg, regm, flags=(CF,) +}; + +def macroop BT_M_R { + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + add t2, t2, base + ld t1, seg, [scale, index, t2], disp + sext t0, t1, reg, flags=(CF,) +}; + +def macroop BT_P_R { + rdip t7 + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + ld t1, seg, [1, t2, t7] + sext t0, t1, reg, flags=(CF,) +}; + +def macroop BTC_R_I { + sexti t0, reg, imm, flags=(CF,) + limm t1, 1 + roli t1, t1, imm + xor reg, reg, t1 +}; + +def macroop BTC_M_I { + limm t1, imm + # This fudges just a tiny bit, but it's reasonable to expect the + # microcode generation logic to have the log of the various sizes + # floating around as well. + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + add t2, t2, base + limm t3, 1 + roli t3, t3, imm + ldst t1, seg, [scale, index, t2], disp + sexti t0, t1, imm, flags=(CF,) + xor t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; + +def macroop BTC_P_I { + rdip t7 + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + limm t3, 1 + roli t3, t3, imm + ldst t1, seg, [1, t2, t7] + sexti t0, t1, imm, flags=(CF,) + xor t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; + +def macroop BTC_R_R { + sext t0, reg, regm, flags=(CF,) + limm t1, 1 + rol t1, t1, regm + xor reg, reg, t1 +}; + +def macroop BTC_M_R { + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + add t2, t2, base + limm t3, 1 + rol t3, t3, reg + ldst t1, seg, [scale, index, t2], disp + sext t0, t1, reg, flags=(CF,) + xor t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; + +def macroop BTC_P_R { + rdip t7 + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + limm t3, 1 + rol t3, t3, reg + ldst t1, seg, [1, t2, t7] + sext t0, t1, reg, flags=(CF,) + xor t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; + +def macroop BTR_R_I { + sexti t0, reg, imm, flags=(CF,) + limm t1, "(uint64_t(-(2ULL)))" + roli t1, t1, imm + and reg, reg, t1 +}; + +def macroop BTR_M_I { + limm t1, imm + # This fudges just a tiny bit, but it's reasonable to expect the + # microcode generation logic to have the log of the various sizes + # floating around as well. + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + add t2, t2, base + limm t3, "(uint64_t(-(2ULL)))" + roli t3, t3, imm + ldst t1, seg, [scale, index, t2], disp + sexti t0, t1, imm, flags=(CF,) + and t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; + +def macroop BTR_P_I { + rdip t7 + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + limm t3, "(uint64_t(-(2ULL)))" + roli t3, t3, imm + ldst t1, seg, [1, t2, t7] + sexti t0, t1, imm, flags=(CF,) + and t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; + +def macroop BTR_R_R { + sext t0, reg, regm, flags=(CF,) + limm t1, "(uint64_t(-(2ULL)))" + rol t1, t1, regm + and reg, reg, t1 +}; + +def macroop BTR_M_R { + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + add t2, t2, base + limm t3, "(uint64_t(-(2ULL)))" + rol t3, t3, reg + ldst t1, seg, [scale, index, t2], disp + sext t0, t1, reg, flags=(CF,) + and t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; + +def macroop BTR_P_R { + rdip t7 + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + limm t3, "(uint64_t(-(2ULL)))" + rol t3, t3, reg + ldst t1, seg, [1, t2, t7] + sext t0, t1, reg, flags=(CF,) + and t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; + +def macroop BTS_R_I { + sexti t0, reg, imm, flags=(CF,) + limm t1, 1 + roli t1, t1, imm + or reg, reg, t1 +}; + +def macroop BTS_M_I { + limm t1, imm + # This fudges just a tiny bit, but it's reasonable to expect the + # microcode generation logic to have the log of the various sizes + # floating around as well. + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + add t2, t2, base + limm t3, 1 + roli t3, t3, imm + ldst t1, seg, [scale, index, t2], disp + sexti t0, t1, imm, flags=(CF,) + or t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; + +def macroop BTS_P_I { + rdip t7 + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + limm t3, 1 + roli t3, t3, imm + ldst t1, seg, [1, t2, t7] + sexti t0, t1, imm, flags=(CF,) + or t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; + +def macroop BTS_R_R { + sext t0, reg, regm, flags=(CF,) + limm t1, 1 + rol t1, t1, regm + or reg, reg, t1 +}; + +def macroop BTS_M_R { + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + add t2, t2, base + limm t3, 1 + rol t3, t3, reg + ldst t1, seg, [scale, index, t2], disp + sext t0, t1, reg, flags=(CF,) + or t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; + +def macroop BTS_P_R { + rdip t7 + limm t1, imm + srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)" + limm t3, 1 + rol t3, t3, reg + ldst t1, seg, [1, t2, t7] + sext t0, t1, reg, flags=(CF,) + or t1, t1, t3 + st t1, seg, [scale, index, t2], disp +}; +''' diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/sign_extension.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/sign_extension.py index 9a7c226af..ae3c6cc6f 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_conversion/sign_extension.py +++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/sign_extension.py @@ -55,7 +55,7 @@ microcode = ''' def macroop CDQE_R { - sext reg, reg, "env.dataSize << 2" + sexti reg, reg, "env.dataSize << 2 - 1" }; def macroop CQO_R_R { 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 c2ccb9d19..d6ae7885a 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 @@ -55,7 +55,7 @@ microcode = ''' def macroop XLAT { - zext t1, rax, 8 + zexti t1, rax, 7 # 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. diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 04f9ea12a..a15fc21ef 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -111,48 +111,48 @@ def macroop MOV_P_I { # def macroop MOVSXD_R_R { - sext reg, regm, 32 + sexti reg, regm, 31 }; def macroop MOVSXD_R_M { ld t1, seg, sib, disp, dataSize=4 - sext reg, t1, 32 + sexti reg, t1, 31 }; def macroop MOVSXD_R_P { rdip t7 ld t1, seg, riprel, disp, dataSize=4 - sext reg, t1, 32 + sexti reg, t1, 31 }; def macroop MOVSX_B_R_R { - sext reg, regm, 8 + sexti reg, regm, 7 }; def macroop MOVSX_B_R_M { ld reg, seg, sib, disp, dataSize=1 - sext reg, reg, 8 + sexti reg, reg, 7 }; def macroop MOVSX_B_R_P { rdip t7 ld reg, seg, riprel, disp, dataSize=1 - sext reg, reg, 8 + sexti reg, reg, 7 }; def macroop MOVSX_W_R_R { - sext reg, regm, 16 + sexti reg, regm, 15 }; def macroop MOVSX_W_R_M { ld reg, seg, sib, disp, dataSize=2 - sext reg, reg, 16 + sexti reg, reg, 15 }; def macroop MOVSX_W_R_P { rdip t7 ld reg, seg, riprel, disp, dataSize=2 - sext reg, reg, 16 + sexti reg, reg, 15 }; # @@ -160,33 +160,37 @@ def macroop MOVSX_W_R_P { # def macroop MOVZX_B_R_R { - zext reg, regm, 8 + zexti reg, regm, 7 }; def macroop MOVZX_B_R_M { ld t1, seg, sib, disp, dataSize=1 - zext reg, t1, 8 + zexti reg, t1, 7 }; def macroop MOVZX_B_R_P { rdip t7 ld t1, seg, riprel, disp, dataSize=1 - zext reg, t1, 8 + zexti reg, t1, 7 }; def macroop MOVZX_W_R_R { - zext reg, regm, 16 + zexti reg, regm, 15 }; def macroop MOVZX_W_R_M { ld t1, seg, sib, disp, dataSize=2 - zext reg, t1, 16 + zexti reg, t1, 15 }; def macroop MOVZX_W_R_P { rdip t7 ld t1, seg, riprel, disp, dataSize=2 - zext reg, t1, 16 + zexti reg, t1, 15 +}; + +def macroop MOV_C_R { + wrcr reg, regm }; ''' #let {{ diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py index 5884d68c2..6c51f3171 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py @@ -162,9 +162,9 @@ def macroop ENTER_I_I { # Pull the different components out of the immediate limm t1, imm - zext t2, t1, 16, dataSize=2 + zexti t2, t1, 15, dataSize=2 srl t1, t1, 16 - zext t1, t1, 6 + zexti t1, t1, 5 # t1 is now the masked nesting level, and t2 is the amount of storage. # Push rbp. 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 c01a11035..75a361eb7 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 @@ -62,7 +62,7 @@ microcode = ''' def macroop IN_R_R { limm t1, "IntAddrPrefixIO" - zext t2, regm, 16, dataSize=2 + zexti t2, regm, 15, dataSize=2 ld reg, intseg, [1, t1, t2], addressSize=8 }; @@ -74,7 +74,7 @@ microcode = ''' def macroop OUT_R_R { limm t1, "IntAddrPrefixIO" - zext t2, reg, 16, dataSize=2 + zexti t2, reg, 15, 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 a8acbbc39..b44203d9c 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 @@ -62,7 +62,7 @@ def macroop INS_M_R { mov t3, t3, t4, flags=(nCEZF,), dataSize=asz limm t1, "IntAddrPrefixIO" - zext t2, reg, 16, dataSize=2 + zexti t2, reg, 15, dataSize=2 ld t6, intseg, [1, t1, t2], addressSize=8 st t6, es, [1, t0, rdi] @@ -78,7 +78,7 @@ def macroop INS_E_M_R { mov t3, t3, t4, flags=(nCEZF,), dataSize=asz limm t1, "IntAddrPrefixIO" - zext t2, reg, 16, dataSize=2 + zexti t2, reg, 15, dataSize=2 topOfLoop: ld t6, intseg, [1, t1, t2], addressSize=8 @@ -98,7 +98,7 @@ def macroop OUTS_R_M { mov t3, t3, t4, flags=(nCEZF,), dataSize=asz limm t1, "IntAddrPrefixIO" - zext t2, reg, 16, dataSize=2 + zexti t2, reg, 15, dataSize=2 ld t6, ds, [1, t0, rsi] st t6, intseg, [1, t1, t2], addressSize=8 @@ -114,7 +114,7 @@ def macroop OUTS_E_R_M { mov t3, t3, t4, flags=(nCEZF,), dataSize=asz limm t1, "IntAddrPrefixIO" - zext t2, reg, 16, dataSize=2 + zexti t2, reg, 15, dataSize=2 topOfLoop: ld t6, ds, [1, t0, rsi] diff --git a/src/arch/x86/isa/insts/system/msrs.py b/src/arch/x86/isa/insts/system/msrs.py index ea576510b..20b9b2a0b 100644 --- a/src/arch/x86/isa/insts/system/msrs.py +++ b/src/arch/x86/isa/insts/system/msrs.py @@ -54,7 +54,7 @@ # Authors: Gabe Black microcode = ''' -def macroop WRMSR +def macroop RDMSR { limm t1, "IntAddrPrefixMSR >> 3" ld t2, intseg, [8, t1, rcx], dataSize=8, addressSize=4 @@ -63,7 +63,7 @@ def macroop WRMSR mov rdx, rdx, t2, dataSize=4 }; -def macroop RDMSR +def macroop WRMSR { limm t1, "IntAddrPrefixMSR >> 3" mov t2, t2, rdx, dataSize=4 diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 0c43d4c13..040bb2036 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -108,11 +108,14 @@ let {{ # This segment selects an internal address space mapped to MSRs, # CPUID info, etc. - assembler.symbols["intseg"] = "NUM_SEGMENTREGS" + assembler.symbols["intseg"] = "SEGMENT_REG_INT" for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di'): assembler.symbols["r%s" % reg] = "INTREG_R%s" % reg.upper() + for reg in range(15): + assembler.symbols["cr%d" % reg] = "MISCREG_CR%d" % reg + for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF'): assembler.symbols[flag] = flag + "Bit" diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 61adde8d1..77152a190 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -123,7 +123,7 @@ def template MicroLoadExecute {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = read(xc, EA, Mem, (%(mem_flags)s) | (1 << segment)); + fault = read(xc, EA, Mem, (%(mem_flags)s) | segment); if(fault == NoFault) { @@ -150,7 +150,7 @@ def template MicroLoadInitiateAcc {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = read(xc, EA, Mem, (%(mem_flags)s) | (1 << segment)); + fault = read(xc, EA, Mem, (%(mem_flags)s) | segment); return fault; } @@ -197,7 +197,7 @@ def template MicroStoreExecute {{ if(fault == NoFault) { - fault = write(xc, Mem, EA, (%(mem_flags)s) | (1 << segment)); + fault = write(xc, Mem, EA, (%(mem_flags)s) | segment); if(fault == NoFault) { %(op_wb)s; @@ -224,7 +224,7 @@ def template MicroStoreInitiateAcc {{ if(fault == NoFault) { - fault = write(xc, Mem, EA, (%(mem_flags)s) | (1 << segment)); + fault = write(xc, Mem, EA, (%(mem_flags)s) | segment); if(fault == NoFault) { %(op_wb)s; diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 892c44487..4ac3a9d98 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -318,7 +318,7 @@ let {{ # If there's something optional to do with flags, generate # a version without it and fix up this version to use it. - if flag_code is not "" or cond_check is not "true": + if flag_code != "" or cond_check != "true": self.buildCppClasses(name, Name, suffix, code, "", "true", else_code) suffix = "Flags" + suffix @@ -835,7 +835,7 @@ let {{ ''' class Wrip(WrRegOp, CondRegOp): - code = 'RIP = psrc1 + sop2' + code = 'RIP = psrc1 + sop2 + CSBase' else_code="RIP = RIP;" class Br(WrRegOp, CondRegOp): @@ -846,7 +846,7 @@ let {{ code = 'ccFlagBits = psrc1 ^ op2' class Rdip(RdRegOp): - code = 'DestReg = RIP' + code = 'DestReg = RIP - CSBase' class Ruflags(RdRegOp): code = 'DestReg = ccFlagBits' @@ -866,12 +866,74 @@ let {{ class Sext(RegOp): code = ''' IntReg val = psrc1; - int sign_bit = bits(val, imm8-1, imm8-1); - uint64_t maskVal = mask(imm8); + // Mask the bit position so that it wraps. + int bitPos = op2 & (dataSize * 8 - 1); + int sign_bit = bits(val, bitPos, bitPos); + uint64_t maskVal = mask(bitPos+1); val = sign_bit ? (val | ~maskVal) : (val & maskVal); DestReg = merge(DestReg, val, dataSize); ''' + flag_code = ''' + if (!sign_bit) + ccFlagBits = ccFlagBits & + ~(ext & (CFBit | ECFBit | ZFBit | EZFBit)); + else + ccFlagBits = ccFlagBits | + (ext & (CFBit | ECFBit | ZFBit | EZFBit)); + ''' class Zext(RegOp): - code = 'DestReg = bits(psrc1, imm8-1, 0);' + code = 'DestReg = bits(psrc1, op2, 0);' + + class Wrcr(RegOp): + def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): + super(Wrcr, self).__init__(dest, \ + src1, "NUM_INTREGS", flags, dataSize) + code = ''' + if (dest == 1 || (dest > 4 && dest < 8) || (dest > 8)) { + fault = new InvalidOpcode(); + } else { + // There are *s in the line below so it doesn't confuse the + // parser. They may be unnecessary. + //Mis*cReg old*Val = pick(Cont*rolDest, 0, dat*aSize); + MiscReg newVal = psrc1; + + // Check for any modifications that would cause a fault. + switch(dest) { + case 0: + { + Efer efer = EferOp; + CR0 cr0 = newVal; + CR4 oldCr4 = CR4Op; + if (bits(newVal, 63, 32) || + (!cr0.pe && cr0.pg) || + (!cr0.cd && cr0.nw) || + (cr0.pg && efer.lme && !oldCr4.pae)) + fault = new GeneralProtection(0); + } + break; + case 2: + break; + case 3: + break; + case 4: + { + CR4 cr4 = newVal; + // PAE can't be disabled in long mode. + if (bits(newVal, 63, 11) || + (machInst.mode.mode == LongMode && !cr4.pae)) + fault = new GeneralProtection(0); + } + break; + case 8: + { + if (bits(newVal, 63, 4)) + fault = new GeneralProtection(0); + } + default: + panic("Unrecognized control register %d.\\n", dest); + } + ControlDest = newVal; + } + ''' }}; diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 8c0eacca2..f50e71727 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -122,5 +122,10 @@ def operands {{ # instructions don't map their indexes with an old value. 'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 61), 'SegBase': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70), + 'ControlDest': ('ControlReg', 'uqw', 'MISCREG_CR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 71), + 'ControlSrc1': ('ControlReg', 'uqw', 'MISCREG_CR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 72), + 'EferOp': ('ControlReg', 'uqw', 'MISCREG_EFER', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 73), + 'CR4Op': ('ControlReg', 'uqw', 'MISCREG_CR4', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 74), + 'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 80), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100) }}; diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa index cf6b6ff86..3802d8949 100644 --- a/src/arch/x86/isa/specialize.isa +++ b/src/arch/x86/isa/specialize.isa @@ -153,7 +153,13 @@ let {{ return doRipRelativeDecode(Name, opTypes, env) elif opType.tag == None or opType.size == None: raise Exception, "Problem parsing operand tag: %s" % opType.tag - elif opType.tag in ("C", "D", "G", "P", "S", "T", "V"): + elif opType.tag == "C": + env.addReg(ModRMRegIndex) + Name += "_C" + elif opType.tag == "D": + env.addReg(ModRMRegIndex) + Name += "_D" + elif opType.tag in ("G", "P", "S", "T", "V"): # Use the "reg" field of the ModRM byte to select the register env.addReg(ModRMRegIndex) Name += "_R" |