Make the operand size reflect the size specifier on the operand tags, and implement NEG
--HG-- extra : convert_revision : da73ed6820d57f083c18f44b2fa868fc0976dd16
This commit is contained in:
parent
089fce4f59
commit
85f9415a67
5 changed files with 95 additions and 25 deletions
|
@ -72,7 +72,7 @@
|
||||||
default: MultiInst::ADD(OPCODE_OP_BOTTOM3,
|
default: MultiInst::ADD(OPCODE_OP_BOTTOM3,
|
||||||
[Eb,Gb], [Ev,Gv],
|
[Eb,Gb], [Ev,Gv],
|
||||||
[Gb,Eb], [Gv,Ev],
|
[Gb,Eb], [Gv,Ev],
|
||||||
[rAl,Ib], [rAx,Iz]);
|
[rAb,Ib], [rAv,Iz]);
|
||||||
}
|
}
|
||||||
0x01: decode OPCODE_OP_BOTTOM3 {
|
0x01: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x6: decode MODE_SUBMODE {
|
0x6: decode MODE_SUBMODE {
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
default: MultiInst::OR(OPCODE_OP_BOTTOM3,
|
default: MultiInst::OR(OPCODE_OP_BOTTOM3,
|
||||||
[Eb,Gb], [Ev,Gv],
|
[Eb,Gb], [Ev,Gv],
|
||||||
[Gb,Eb], [Gv,Ev],
|
[Gb,Eb], [Gv,Ev],
|
||||||
[rAl,Ib], [rAx,Iz]);
|
[rAb,Ib], [rAv,Iz]);
|
||||||
}
|
}
|
||||||
0x02: decode OPCODE_OP_BOTTOM3 {
|
0x02: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x6: decode MODE_SUBMODE {
|
0x6: decode MODE_SUBMODE {
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
default: MultiInst::ADC(OPCODE_OP_BOTTOM3,
|
default: MultiInst::ADC(OPCODE_OP_BOTTOM3,
|
||||||
[Eb,Gb], [Ev,Gv],
|
[Eb,Gb], [Ev,Gv],
|
||||||
[Gb,Eb], [Gv,Ev],
|
[Gb,Eb], [Gv,Ev],
|
||||||
[rAl,Ib], [rAx,Iz]);
|
[rAb,Ib], [rAv,Iz]);
|
||||||
}
|
}
|
||||||
0x03: decode OPCODE_OP_BOTTOM3 {
|
0x03: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x6: decode MODE_SUBMODE {
|
0x6: decode MODE_SUBMODE {
|
||||||
|
@ -113,7 +113,7 @@
|
||||||
default: MultiInst::SBB(OPCODE_OP_BOTTOM3,
|
default: MultiInst::SBB(OPCODE_OP_BOTTOM3,
|
||||||
[Eb,Gb], [Ev,Gv],
|
[Eb,Gb], [Ev,Gv],
|
||||||
[Gb,Eb], [Gv,Ev],
|
[Gb,Eb], [Gv,Ev],
|
||||||
[rAl,Ib], [rAx,Iz]);
|
[rAb,Ib], [rAv,Iz]);
|
||||||
}
|
}
|
||||||
0x04: decode OPCODE_OP_BOTTOM3 {
|
0x04: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x6: M5InternalError::error(
|
0x6: M5InternalError::error(
|
||||||
|
@ -125,7 +125,7 @@
|
||||||
default: MultiInst::AND(OPCODE_OP_BOTTOM3,
|
default: MultiInst::AND(OPCODE_OP_BOTTOM3,
|
||||||
[Eb,Gb], [Ev,Gv],
|
[Eb,Gb], [Ev,Gv],
|
||||||
[Gb,Eb], [Gv,Ev],
|
[Gb,Eb], [Gv,Ev],
|
||||||
[rAl,Ib], [rAx,Iz]);
|
[rAb,Ib], [rAv,Iz]);
|
||||||
}
|
}
|
||||||
0x05: decode OPCODE_OP_BOTTOM3 {
|
0x05: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x6: M5InternalError::error(
|
0x6: M5InternalError::error(
|
||||||
|
@ -134,7 +134,7 @@
|
||||||
default: MultiInst::SUB(OPCODE_OP_BOTTOM3,
|
default: MultiInst::SUB(OPCODE_OP_BOTTOM3,
|
||||||
[Eb,Gb], [Ev,Gv],
|
[Eb,Gb], [Ev,Gv],
|
||||||
[Gb,Eb], [Gv,Ev],
|
[Gb,Eb], [Gv,Ev],
|
||||||
[rAl,Ib], [rAx,Iz]);
|
[rAb,Ib], [rAv,Iz]);
|
||||||
}
|
}
|
||||||
0x06: decode OPCODE_OP_BOTTOM3 {
|
0x06: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x6: M5InternalError::error(
|
0x6: M5InternalError::error(
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
default: MultiInst::XOR(OPCODE_OP_BOTTOM3,
|
default: MultiInst::XOR(OPCODE_OP_BOTTOM3,
|
||||||
[Eb,Gb], [Ev,Gv],
|
[Eb,Gb], [Ev,Gv],
|
||||||
[Gb,Eb], [Gv,Ev],
|
[Gb,Eb], [Gv,Ev],
|
||||||
[rAl,Ib], [rAx,Iz]);
|
[rAb,Ib], [rAv,Iz]);
|
||||||
}
|
}
|
||||||
0x07: decode OPCODE_OP_BOTTOM3 {
|
0x07: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x6: M5InternalError::error(
|
0x6: M5InternalError::error(
|
||||||
|
@ -158,7 +158,7 @@
|
||||||
default: MultiInst::CMP(OPCODE_OP_BOTTOM3,
|
default: MultiInst::CMP(OPCODE_OP_BOTTOM3,
|
||||||
[Eb,Gb], [Ev,Gv],
|
[Eb,Gb], [Ev,Gv],
|
||||||
[Gb,Eb], [Gv,Ev],
|
[Gb,Eb], [Gv,Ev],
|
||||||
[rAl,Ib], [rAx,Iz]);
|
[rAb,Ib], [rAv,Iz]);
|
||||||
}
|
}
|
||||||
0x08: decode MODE_SUBMODE {
|
0x08: decode MODE_SUBMODE {
|
||||||
0x0: M5InternalError::error (
|
0x0: M5InternalError::error (
|
||||||
|
@ -188,7 +188,10 @@
|
||||||
default: bound_Gv_Ma();
|
default: bound_Gv_Ma();
|
||||||
}
|
}
|
||||||
0x3: decode MODE_SUBMODE {
|
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();
|
default: arpl_Ew_Gw();
|
||||||
}
|
}
|
||||||
0x4: M5InternalError::error(
|
0x4: M5InternalError::error(
|
||||||
|
@ -333,8 +336,8 @@
|
||||||
0x7: cmps_Yv_Xv();
|
0x7: cmps_Yv_Xv();
|
||||||
}
|
}
|
||||||
0x15: decode OPCODE_OP_BOTTOM3 {
|
0x15: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x0: Inst::TEST(rAl,Ib);
|
0x0: Inst::TEST(rAb,Ib);
|
||||||
0x1: Inst::TEST(rAX,Iz);
|
0x1: Inst::TEST(rAv,Iz);
|
||||||
0x2: stos_Yb_Al();
|
0x2: stos_Yb_Al();
|
||||||
0x3: stos_Yv_rAX();
|
0x3: stos_Yv_rAX();
|
||||||
0x4: lods_Al_Xb();
|
0x4: lods_Al_Xb();
|
||||||
|
@ -465,8 +468,28 @@
|
||||||
{{"Tried to execute the rep/repe prefix!"}});
|
{{"Tried to execute the rep/repe prefix!"}});
|
||||||
0x4: hlt();
|
0x4: hlt();
|
||||||
0x5: cmc();
|
0x5: cmc();
|
||||||
0x6: group3_Eb();
|
//0x6: group3_Eb();
|
||||||
0x7: group3_Ev();
|
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 {
|
0x1F: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x0: clc();
|
0x0: clc();
|
||||||
|
|
|
@ -296,8 +296,11 @@
|
||||||
0x3: btr_Ev_Gv();
|
0x3: btr_Ev_Gv();
|
||||||
0x4: lfs_Gz_Mp();
|
0x4: lfs_Gz_Mp();
|
||||||
0x5: lgs_Gz_Mp();
|
0x5: lgs_Gz_Mp();
|
||||||
0x6: Inst::MOVZX_B(Gv,Eb);
|
//The size of the second operand in these instructions should
|
||||||
0x7: Inst::MOVZX_W(Gv,Ew);
|
//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 {
|
0x17: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x0: jmpe_Jz(); // IA-64?
|
0x0: jmpe_Jz(); // IA-64?
|
||||||
|
@ -306,8 +309,11 @@
|
||||||
0x3: btc_Ev_Gv();
|
0x3: btc_Ev_Gv();
|
||||||
0x4: bsf_Gv_Ev();
|
0x4: bsf_Gv_Ev();
|
||||||
0x5: bsr_Gv_Ev();
|
0x5: bsr_Gv_Ev();
|
||||||
0x6: Inst::MOVSX_B(Gv,Eb);
|
//The size of the second operand in these instructions should
|
||||||
0x7: Inst::MOVSX_W(Gv,Ew);
|
//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 {
|
0x18: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x0: holder();
|
0x0: holder();
|
||||||
|
|
|
@ -277,6 +277,26 @@ def macroop SBB_P_R
|
||||||
sbb t1, t1, reg
|
sbb t1, t1, reg
|
||||||
st t1, ds, [scale, index, base], disp
|
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 {{
|
#let {{
|
||||||
# class ADC(Inst):
|
# class ADC(Inst):
|
||||||
|
|
|
@ -196,18 +196,34 @@ let {{
|
||||||
self.regUsed = False
|
self.regUsed = False
|
||||||
self.regm = "0"
|
self.regm = "0"
|
||||||
self.regmUsed = False
|
self.regmUsed = False
|
||||||
|
self.size = None
|
||||||
self.addressSize = "ADDRSIZE"
|
self.addressSize = "ADDRSIZE"
|
||||||
self.dataSize = "OPSIZE"
|
self.dataSize = "OPSIZE"
|
||||||
self.stackSize = "STACKSIZE"
|
self.stackSize = "STACKSIZE"
|
||||||
self.doModRM = False
|
self.doModRM = False
|
||||||
|
|
||||||
def getAllocator(self):
|
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,
|
return '''EmulEnv(%(reg)s,
|
||||||
%(regm)s,
|
%(regm)s,
|
||||||
%(dataSize)s,
|
%(dataSize)s,
|
||||||
%(addressSize)s,
|
%(addressSize)s,
|
||||||
%(stackSize)s)''' % \
|
%(stackSize)s)''' % \
|
||||||
self.__dict__
|
self.__dict__
|
||||||
|
|
||||||
def addReg(self, reg):
|
def addReg(self, reg):
|
||||||
if not self.regUsed:
|
if not self.regUsed:
|
||||||
self.reg = reg
|
self.reg = reg
|
||||||
|
@ -217,6 +233,13 @@ let {{
|
||||||
self.regmUsed = True
|
self.regmUsed = True
|
||||||
else:
|
else:
|
||||||
raise Exception, "EmulEnv is out of register specialization spots."
|
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 {{
|
let {{
|
||||||
|
|
|
@ -114,7 +114,8 @@ let {{
|
||||||
self.reg = match.group("reg")
|
self.reg = match.group("reg")
|
||||||
self.tag = match.group("tag")
|
self.tag = match.group("tag")
|
||||||
self.size = match.group("size")
|
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))"
|
ModRMRegIndex = "(MODRM_REG | (REX_R << 3))"
|
||||||
ModRMRMIndex = "(MODRM_RM | (REX_B << 3))"
|
ModRMRMIndex = "(MODRM_RM | (REX_B << 3))"
|
||||||
|
@ -129,6 +130,10 @@ let {{
|
||||||
opType = OpType(opTypes[0])
|
opType = OpType(opTypes[0])
|
||||||
opTypes.pop(0)
|
opTypes.pop(0)
|
||||||
|
|
||||||
|
if opType.tag not in ("I", "J"):
|
||||||
|
if opType.size:
|
||||||
|
env.setSize(opType.size)
|
||||||
|
|
||||||
if opType.reg:
|
if opType.reg:
|
||||||
#Figure out what to do with fixed register operands
|
#Figure out what to do with fixed register operands
|
||||||
#This is the index to use, so we should stick it some place.
|
#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)
|
env.addReg("INTREG_R%sX | (REX_B << 3)" % opType.reg)
|
||||||
else:
|
else:
|
||||||
env.addReg("INTREG_R%s | (REX_B << 3)" % opType.reg)
|
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"
|
Name += "_R"
|
||||||
elif opType.tag == "B":
|
elif opType.tag == "B":
|
||||||
# This refers to registers whose index is encoded as part of the opcode
|
# This refers to registers whose index is encoded as part of the opcode
|
||||||
|
|
Loading…
Reference in a new issue