def format MultiInst(switchVal, *opTypeSets) {{
switcher = {}
for (count, opTypeSet) in zip(xrange(len(opTypeSets)), opTypeSets):
- switcher[count] = (Name, opTypeSet, EmulEnv())
- blocks = doSplitDecode(specializeInst, switchVal, switcher)
+ switcher[count] = (specializeInst, Name, opTypeSet, EmulEnv())
+ blocks = doSplitDecode(switchVal, switcher)
(header_output, decoder_output,
decode_block, exec_output) = blocks.makeList()
}};
def macroop SUB_M_I
{
- #Load into t1
+ ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
subi "NUM_INTREGS+1", "NUM_INTREGS+1", "IMMEDIATE"
- #save from t1
+ st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+};
+
+def macroop SUB_P_I
+{
+ rdip "NUM_INTREGS+7"
+ ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+ subi "NUM_INTREGS+1", "NUM_INTREGS+1", "IMMEDIATE"
+ st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
};
'''
#let {{
and "NUM_INTREGS", "NUM_INTREGS+1", "env.reg"
};
+def macroop TEST_P_R
+{
+ rdip "NUM_INTREGS+7"
+ ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+ and "NUM_INTREGS", "NUM_INTREGS+1", "env.reg"
+};
+
def macroop TEST_R_R
{
and "NUM_INTREGS", "env.reg", "env.regm"
and "NUM_INTREGS", "NUM_INTREGS+1", "NUM_INTREGS+2"
};
+def macroop TEST_P_I
+{
+ rdip "NUM_INTREGS+7"
+ ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+ limm "NUM_INTREGS+2", "IMMEDIATE"
+ and "NUM_INTREGS", "NUM_INTREGS+1", "NUM_INTREGS+2"
+};
+
def macroop TEST_R_I
{
limm "NUM_INTREGS+1", "IMMEDIATE"
st "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
};
+def macroop MOV_P_R {
+ rdip "NUM_INTREGS+7"
+ st "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
+};
+
def macroop MOV_R_M {
ld "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
};
+def macroop MOV_R_P {
+ rdip "NUM_INTREGS+7"
+ ld "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
+};
+
def macroop MOV_R_I {
limm "env.reg", "IMMEDIATE"
};
def macroop MOV_M_I {
- limm "env.reg", "IMMEDIATE"
- #Do a store to put the register operand into memory
+ limm "NUM_INTREGS+1", "IMMEDIATE"
+ st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+};
+
+def macroop MOV_P_I {
+ rdip "NUM_INTREGS+7"
+ limm "NUM_INTREGS+1", "IMMEDIATE"
+ st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
};
def macroop MOVSXD_R_R {
};
def macroop MOVSXD_R_M {
- #Do a load to fill the register operand from memory
- sext "env.reg", "env.regm", "env.dataSize"
+ ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+ sext "env.reg", "NUM_INTREGS+1", "env.dataSize"
+};
+
+def macroop MOVSXD_R_P {
+ rdip "NUM_INTREGS+7"
+ ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+ sext "env.reg", "NUM_INTREGS+1", "env.dataSize"
};
'''
#let {{
def macroop LEA_R_M {
lea "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
};
+
+def macroop LEA_R_P {
+ rdip "NUM_INTREGS+7"
+ lea "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
+};
'''
def macroop XOR_M_R
{
- #Do a load to get one of the sources
+ ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
xor "NUM_INTREGS+1", "NUM_INTREGS+1", "env.reg"
- #Do a store to write the destination
+ st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+};
+
+def macroop XOR_P_R
+{
+ rdip "NUM_INTREGS+7"
+ ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+ xor "NUM_INTREGS+1", "NUM_INTREGS+1", "env.reg"
+ st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
};
def macroop XOR_R_M
{
- #Do a load to get one of the sources
+ ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+ xor "env.reg", "env.reg", "NUM_INTREGS+1"
+};
+
+def macroop XOR_R_P
+{
+ rdip "NUM_INTREGS+7"
+ ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
xor "env.reg", "env.reg", "NUM_INTREGS+1"
};
def macroop AND_M_I
{
- #Do a load to get one of the sources
+ ld "NUM_INTREGS+2", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+ limm "NUM_INTREGS+1", "IMMEDIATE"
+ and "NUM_INTREGS+2", "NUM_INTREGS+2", "NUM_INTREGS+1"
+ st "NUM_INTREGS+2", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
+};
+
+def macroop AND_P_I
+{
+ rdip "NUM_INTREGS+7"
+ ld "NUM_INTREGS+2", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
limm "NUM_INTREGS+1", "IMMEDIATE"
- and "NUM_INTREGS+1", "NUM_INTREGS+1", "NUM_INTREGS+2"
- #Do a store to write the destination
+ and "NUM_INTREGS+2", "NUM_INTREGS+2", "NUM_INTREGS+1"
+ st "NUM_INTREGS+2", 3, ["env.scale", "env.index", "env.base"], \
+ "DISPLACEMENT"
};
'''
#let {{
let {{
# This code builds up a decode block which decodes based on switchval.
# vals is a dict which matches case values with what should be decoded to.
- # builder is called on the exploded contents of "vals" values to generate
- # whatever code should be used.
- def doSplitDecode(builder, switchVal, vals, default = None):
+ # Each element of the dict is a list containing a function and then the
+ # arguments to pass to it.
+ def doSplitDecode(switchVal, vals, default = None):
blocks = OutputBlocks()
blocks.decode_block = 'switch(%s) {\n' % switchVal
for (val, todo) in vals.items():
- new_blocks = builder(*todo)
+ new_blocks = todo[0](*todo[1:])
new_blocks.decode_block = \
'\tcase %s: %s\n' % (val, new_blocks.decode_block)
blocks.append(new_blocks)
if default:
- new_blocks = builder(*default)
+ new_blocks = default[0](*default[1:])
new_blocks.decode_block = \
'\tdefault: %s\n' % new_blocks.decode_block
blocks.append(new_blocks)
return blocks
}};
+let {{
+ def doRipRelativeDecode(Name, opTypes, env):
+ # print "RIPing %s with opTypes %s" % (Name, opTypes)
+ normBlocks = specializeInst(Name + "_M", copy.copy(opTypes), copy.copy(env))
+ ripBlocks = specializeInst(Name + "_P", copy.copy(opTypes), copy.copy(env))
+
+ blocks = OutputBlocks()
+ blocks.append(normBlocks)
+ blocks.append(ripBlocks)
+
+ blocks.decode_block = '''
+ if(machInst.modRM.mod == 0 &&
+ machInst.modRM.rm == 5 &&
+ machInst.mode.submode == SixtyFourBitMode)
+ { %s }
+ else
+ { %s }''' % \
+ (ripBlocks.decode_block, normBlocks.decode_block)
+ return blocks
+}};
+
let {{
class OpType(object):
parser = re.compile(r"(?P<tag>[A-Z]+)(?P<size>[a-z]*)|(r(?P<reg>[A-Z0-9]+)(?P<rsize>[a-z]*))")
# modrm addressing.
memEnv = copy.copy(env)
memEnv.doModRM = True
- return doSplitDecode(specializeInst, "MODRM_MOD",
- {"3" : (Name + "_R", copy.copy(opTypes), regEnv)},
- (Name + "_M", copy.copy(opTypes), memEnv))
+ return doSplitDecode("MODRM_MOD",
+ {"3" : (specializeInst, Name + "_R", copy.copy(opTypes), regEnv)},
+ (doRipRelativeDecode, Name, copy.copy(opTypes), memEnv))
elif opType.tag in ("I", "J"):
# Immediates
Name += "_I"