summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa49
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa14
-rw-r--r--src/arch/x86/isa/insts/arithmetic/add_and_subtract.py20
-rw-r--r--src/arch/x86/isa/macroop.isa23
-rw-r--r--src/arch/x86/isa/specialize.isa14
5 files changed, 95 insertions, 25 deletions
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index b28f2029c..9a70e9f4f 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -72,7 +72,7 @@
default: MultiInst::ADD(OPCODE_OP_BOTTOM3,
[Eb,Gb], [Ev,Gv],
[Gb,Eb], [Gv,Ev],
- [rAl,Ib], [rAx,Iz]);
+ [rAb,Ib], [rAv,Iz]);
}
0x01: decode OPCODE_OP_BOTTOM3 {
0x6: decode MODE_SUBMODE {
@@ -85,7 +85,7 @@
default: MultiInst::OR(OPCODE_OP_BOTTOM3,
[Eb,Gb], [Ev,Gv],
[Gb,Eb], [Gv,Ev],
- [rAl,Ib], [rAx,Iz]);
+ [rAb,Ib], [rAv,Iz]);
}
0x02: decode OPCODE_OP_BOTTOM3 {
0x6: decode MODE_SUBMODE {
@@ -99,7 +99,7 @@
default: MultiInst::ADC(OPCODE_OP_BOTTOM3,
[Eb,Gb], [Ev,Gv],
[Gb,Eb], [Gv,Ev],
- [rAl,Ib], [rAx,Iz]);
+ [rAb,Ib], [rAv,Iz]);
}
0x03: decode OPCODE_OP_BOTTOM3 {
0x6: decode MODE_SUBMODE {
@@ -113,7 +113,7 @@
default: MultiInst::SBB(OPCODE_OP_BOTTOM3,
[Eb,Gb], [Ev,Gv],
[Gb,Eb], [Gv,Ev],
- [rAl,Ib], [rAx,Iz]);
+ [rAb,Ib], [rAv,Iz]);
}
0x04: decode OPCODE_OP_BOTTOM3 {
0x6: M5InternalError::error(
@@ -125,7 +125,7 @@
default: MultiInst::AND(OPCODE_OP_BOTTOM3,
[Eb,Gb], [Ev,Gv],
[Gb,Eb], [Gv,Ev],
- [rAl,Ib], [rAx,Iz]);
+ [rAb,Ib], [rAv,Iz]);
}
0x05: decode OPCODE_OP_BOTTOM3 {
0x6: M5InternalError::error(
@@ -134,7 +134,7 @@
default: MultiInst::SUB(OPCODE_OP_BOTTOM3,
[Eb,Gb], [Ev,Gv],
[Gb,Eb], [Gv,Ev],
- [rAl,Ib], [rAx,Iz]);
+ [rAb,Ib], [rAv,Iz]);
}
0x06: decode OPCODE_OP_BOTTOM3 {
0x6: M5InternalError::error(
@@ -146,7 +146,7 @@
default: MultiInst::XOR(OPCODE_OP_BOTTOM3,
[Eb,Gb], [Ev,Gv],
[Gb,Eb], [Gv,Ev],
- [rAl,Ib], [rAx,Iz]);
+ [rAb,Ib], [rAv,Iz]);
}
0x07: decode OPCODE_OP_BOTTOM3 {
0x6: M5InternalError::error(
@@ -158,7 +158,7 @@
default: MultiInst::CMP(OPCODE_OP_BOTTOM3,
[Eb,Gb], [Ev,Gv],
[Gb,Eb], [Gv,Ev],
- [rAl,Ib], [rAx,Iz]);
+ [rAb,Ib], [rAv,Iz]);
}
0x08: decode MODE_SUBMODE {
0x0: M5InternalError::error (
@@ -188,7 +188,10 @@
default: bound_Gv_Ma();
}
0x3: decode MODE_SUBMODE {
- 0x0: Inst::MOVSXD(Gv,Ed);
+ //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();
}
0x4: M5InternalError::error(
@@ -333,8 +336,8 @@
0x7: cmps_Yv_Xv();
}
0x15: decode OPCODE_OP_BOTTOM3 {
- 0x0: Inst::TEST(rAl,Ib);
- 0x1: Inst::TEST(rAX,Iz);
+ 0x0: Inst::TEST(rAb,Ib);
+ 0x1: Inst::TEST(rAv,Iz);
0x2: stos_Yb_Al();
0x3: stos_Yv_rAX();
0x4: lods_Al_Xb();
@@ -465,8 +468,28 @@
{{"Tried to execute the rep/repe prefix!"}});
0x4: hlt();
0x5: cmc();
- 0x6: group3_Eb();
- 0x7: group3_Ev();
+ //0x6: group3_Eb();
+ 0x6: decode MODRM_REG {
+ 0x0: test_Eb_Iz();
+ 0x1: test_Eb_Iz();
+ 0x2: not_Eb();
+ 0x3: Inst::NEG(Eb);
+ 0x4: mul_Eb();
+ 0x5: imul_Eb();
+ 0x6: div_Eb();
+ 0x7: idiv_Eb();
+ }
+ //0x7: group3_Ev();
+ 0x7: decode MODRM_REG {
+ 0x0: test_Ev_Iz();
+ 0x1: test_Ev_Iz();
+ 0x2: not_Ev();
+ 0x3: Inst::NEG(Ev);
+ 0x4: mul_Ev();
+ 0x5: imul_Ev();
+ 0x6: div_Ev();
+ 0x7: idiv_Ev();
+ }
}
0x1F: decode OPCODE_OP_BOTTOM3 {
0x0: clc();
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
index e5631d37b..3bda044c8 100644
--- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -296,8 +296,11 @@
0x3: btr_Ev_Gv();
0x4: lfs_Gz_Mp();
0x5: lgs_Gz_Mp();
- 0x6: Inst::MOVZX_B(Gv,Eb);
- 0x7: Inst::MOVZX_W(Gv,Ew);
+ //The size of the second operand in these instructions should
+ //really be "b" or "w", but it's set to v in order to have a
+ //consistent register size. This shouldn't affect behavior.
+ 0x6: Inst::MOVZX_B(Gv,Ev);
+ 0x7: Inst::MOVZX_W(Gv,Ev);
}
0x17: decode OPCODE_OP_BOTTOM3 {
0x0: jmpe_Jz(); // IA-64?
@@ -306,8 +309,11 @@
0x3: btc_Ev_Gv();
0x4: bsf_Gv_Ev();
0x5: bsr_Gv_Ev();
- 0x6: Inst::MOVSX_B(Gv,Eb);
- 0x7: Inst::MOVSX_W(Gv,Ew);
+ //The size of the second operand in these instructions should
+ //really be "b" or "w", but it's set to v in order to have a
+ //consistent register size. This shouldn't affect behavior.
+ 0x6: Inst::MOVSX_B(Gv,Ev);
+ 0x7: Inst::MOVSX_W(Gv,Ev);
}
0x18: decode OPCODE_OP_BOTTOM3 {
0x0: holder();
diff --git a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
index 05aa6cd69..e637251d2 100644
--- a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
+++ b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
@@ -277,6 +277,26 @@ def macroop SBB_P_R
sbb t1, t1, reg
st t1, ds, [scale, index, base], disp
};
+
+def macroop NEG_R
+{
+ sub reg, t0, reg, flags=(CF,OF,SF,ZF,AF,PF)
+};
+
+def macroop NEG_M
+{
+ ld t1, ds, [scale, index, base], disp
+ sub t1, t0, t1, flags=(CF,OF,SF,ZF,AF,PF)
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop NEG_P
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ sub t1, t0, t1, flags=(CF,OF,SF,ZF,AF,PF)
+ st t1, ds, [0, t0, t7], disp
+};
'''
#let {{
# class ADC(Inst):
diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa
index 8453a4fe9..4131246a4 100644
--- a/src/arch/x86/isa/macroop.isa
+++ b/src/arch/x86/isa/macroop.isa
@@ -196,18 +196,34 @@ let {{
self.regUsed = False
self.regm = "0"
self.regmUsed = False
+ self.size = None
self.addressSize = "ADDRSIZE"
self.dataSize = "OPSIZE"
self.stackSize = "STACKSIZE"
self.doModRM = False
def getAllocator(self):
+ if self.size == 'b':
+ self.dataSize = 1
+ elif self.size == 'd':
+ self.dataSize = 4
+ elif self.size == 'q':
+ self.dataSize = 8
+ elif self.size == 'v':
+ self.dataSize = "OPSIZE"
+ elif self.size == 'w':
+ self.dataSize = 2
+ elif self.size == 'z':
+ self.dataSize = "((OPSIZE == 8) ? 4 : OPSIZE)"
+ elif self.size:
+ raise Exception, "Unrecognized size type %s!" % self.size
return '''EmulEnv(%(reg)s,
%(regm)s,
%(dataSize)s,
%(addressSize)s,
%(stackSize)s)''' % \
self.__dict__
+
def addReg(self, reg):
if not self.regUsed:
self.reg = reg
@@ -217,6 +233,13 @@ let {{
self.regmUsed = True
else:
raise Exception, "EmulEnv is out of register specialization spots."
+ def setSize(self, size):
+ if not self.size:
+ self.size = size
+ else:
+ if self.size is not size:
+ raise Exception, "Conflicting register sizes %s and %s!" %\
+ (self.size, size)
}};
let {{
diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa
index 5165ea206..a45c6e80f 100644
--- a/src/arch/x86/isa/specialize.isa
+++ b/src/arch/x86/isa/specialize.isa
@@ -114,7 +114,8 @@ let {{
self.reg = match.group("reg")
self.tag = match.group("tag")
self.size = match.group("size")
- self.rsize = match.group("rsize")
+ if not self.size:
+ self.size = match.group("rsize")
ModRMRegIndex = "(MODRM_REG | (REX_R << 3))"
ModRMRMIndex = "(MODRM_RM | (REX_B << 3))"
@@ -129,6 +130,10 @@ let {{
opType = OpType(opTypes[0])
opTypes.pop(0)
+ if opType.tag not in ("I", "J"):
+ if opType.size:
+ env.setSize(opType.size)
+
if opType.reg:
#Figure out what to do with fixed register operands
#This is the index to use, so we should stick it some place.
@@ -136,13 +141,6 @@ let {{
env.addReg("INTREG_R%sX | (REX_B << 3)" % opType.reg)
else:
env.addReg("INTREG_R%s | (REX_B << 3)" % opType.reg)
- if opType.size:
- if opType.rsize in ("l", "h", "b"):
- print "byte"
- elif opType.rsize == "x":
- print "word"
- else:
- print "Didn't recognize fixed register size %s!" % opType.rsize
Name += "_R"
elif opType.tag == "B":
# This refers to registers whose index is encoded as part of the opcode