summaryrefslogtreecommitdiff
path: root/src/arch/x86/isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/isa')
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa222
-rw-r--r--src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_test.py250
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_conversion/sign_extension.py2
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py2
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_transfer/move.py34
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py4
-rw-r--r--src/arch/x86/isa/insts/general_purpose/input_output/general_io.py4
-rw-r--r--src/arch/x86/isa/insts/general_purpose/input_output/string_io.py8
-rw-r--r--src/arch/x86/isa/insts/system/msrs.py4
-rw-r--r--src/arch/x86/isa/microasm.isa5
-rw-r--r--src/arch/x86/isa/microops/ldstop.isa8
-rw-r--r--src/arch/x86/isa/microops/regop.isa74
-rw-r--r--src/arch/x86/isa/operands.isa5
-rw-r--r--src/arch/x86/isa/specialize.isa8
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"