Implement rip relative addressing and put in some missing loads and stores.
--HG-- extra : convert_revision : 99053414cef40f13c5226871a72909b2622d8c26
This commit is contained in:
parent
c4ebfa850e
commit
77aa98d0f8
|
@ -70,8 +70,8 @@ def format Inst(*opTypeSet) {{
|
||||||
def format MultiInst(switchVal, *opTypeSets) {{
|
def format MultiInst(switchVal, *opTypeSets) {{
|
||||||
switcher = {}
|
switcher = {}
|
||||||
for (count, opTypeSet) in zip(xrange(len(opTypeSets)), opTypeSets):
|
for (count, opTypeSet) in zip(xrange(len(opTypeSets)), opTypeSets):
|
||||||
switcher[count] = (Name, opTypeSet, EmulEnv())
|
switcher[count] = (specializeInst, Name, opTypeSet, EmulEnv())
|
||||||
blocks = doSplitDecode(specializeInst, switchVal, switcher)
|
blocks = doSplitDecode(switchVal, switcher)
|
||||||
(header_output, decoder_output,
|
(header_output, decoder_output,
|
||||||
decode_block, exec_output) = blocks.makeList()
|
decode_block, exec_output) = blocks.makeList()
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -61,9 +61,21 @@ def macroop SUB_R_I
|
||||||
|
|
||||||
def macroop SUB_M_I
|
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"
|
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 {{
|
#let {{
|
||||||
|
|
|
@ -61,6 +61,14 @@ def macroop TEST_M_R
|
||||||
and "NUM_INTREGS", "NUM_INTREGS+1", "env.reg"
|
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
|
def macroop TEST_R_R
|
||||||
{
|
{
|
||||||
and "NUM_INTREGS", "env.reg", "env.regm"
|
and "NUM_INTREGS", "env.reg", "env.regm"
|
||||||
|
@ -74,6 +82,15 @@ def macroop TEST_M_I
|
||||||
and "NUM_INTREGS", "NUM_INTREGS+1", "NUM_INTREGS+2"
|
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
|
def macroop TEST_R_I
|
||||||
{
|
{
|
||||||
limm "NUM_INTREGS+1", "IMMEDIATE"
|
limm "NUM_INTREGS+1", "IMMEDIATE"
|
||||||
|
|
|
@ -62,17 +62,35 @@ def macroop MOV_M_R {
|
||||||
st "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
|
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 {
|
def macroop MOV_R_M {
|
||||||
ld "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
|
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 {
|
def macroop MOV_R_I {
|
||||||
limm "env.reg", "IMMEDIATE"
|
limm "env.reg", "IMMEDIATE"
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop MOV_M_I {
|
def macroop MOV_M_I {
|
||||||
limm "env.reg", "IMMEDIATE"
|
limm "NUM_INTREGS+1", "IMMEDIATE"
|
||||||
#Do a store to put the register operand into memory
|
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_R {
|
||||||
|
@ -80,8 +98,16 @@ def macroop MOVSXD_R_R {
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop MOVSXD_R_M {
|
def macroop MOVSXD_R_M {
|
||||||
#Do a load to fill the register operand from memory
|
ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
|
||||||
sext "env.reg", "env.regm", "env.dataSize"
|
"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 {{
|
#let {{
|
||||||
|
|
|
@ -57,4 +57,9 @@ microcode = '''
|
||||||
def macroop LEA_R_M {
|
def macroop LEA_R_M {
|
||||||
lea "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
|
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"
|
||||||
|
};
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -67,14 +67,35 @@ def macroop XOR_R_I
|
||||||
|
|
||||||
def macroop XOR_M_R
|
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"
|
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
|
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"
|
xor "env.reg", "env.reg", "NUM_INTREGS+1"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,10 +107,23 @@ def macroop AND_R_I
|
||||||
|
|
||||||
def macroop AND_M_I
|
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"
|
limm "NUM_INTREGS+1", "IMMEDIATE"
|
||||||
and "NUM_INTREGS+1", "NUM_INTREGS+1", "NUM_INTREGS+2"
|
and "NUM_INTREGS+2", "NUM_INTREGS+2", "NUM_INTREGS+1"
|
||||||
#Do a store to write the destination
|
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+2", "NUM_INTREGS+2", "NUM_INTREGS+1"
|
||||||
|
st "NUM_INTREGS+2", 3, ["env.scale", "env.index", "env.base"], \
|
||||||
|
"DISPLACEMENT"
|
||||||
};
|
};
|
||||||
'''
|
'''
|
||||||
#let {{
|
#let {{
|
||||||
|
|
|
@ -64,18 +64,18 @@
|
||||||
let {{
|
let {{
|
||||||
# This code builds up a decode block which decodes based on switchval.
|
# 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.
|
# 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
|
# Each element of the dict is a list containing a function and then the
|
||||||
# whatever code should be used.
|
# arguments to pass to it.
|
||||||
def doSplitDecode(builder, switchVal, vals, default = None):
|
def doSplitDecode(switchVal, vals, default = None):
|
||||||
blocks = OutputBlocks()
|
blocks = OutputBlocks()
|
||||||
blocks.decode_block = 'switch(%s) {\n' % switchVal
|
blocks.decode_block = 'switch(%s) {\n' % switchVal
|
||||||
for (val, todo) in vals.items():
|
for (val, todo) in vals.items():
|
||||||
new_blocks = builder(*todo)
|
new_blocks = todo[0](*todo[1:])
|
||||||
new_blocks.decode_block = \
|
new_blocks.decode_block = \
|
||||||
'\tcase %s: %s\n' % (val, new_blocks.decode_block)
|
'\tcase %s: %s\n' % (val, new_blocks.decode_block)
|
||||||
blocks.append(new_blocks)
|
blocks.append(new_blocks)
|
||||||
if default:
|
if default:
|
||||||
new_blocks = builder(*default)
|
new_blocks = default[0](*default[1:])
|
||||||
new_blocks.decode_block = \
|
new_blocks.decode_block = \
|
||||||
'\tdefault: %s\n' % new_blocks.decode_block
|
'\tdefault: %s\n' % new_blocks.decode_block
|
||||||
blocks.append(new_blocks)
|
blocks.append(new_blocks)
|
||||||
|
@ -83,6 +83,27 @@ let {{
|
||||||
return 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 {{
|
let {{
|
||||||
class OpType(object):
|
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]*))")
|
parser = re.compile(r"(?P<tag>[A-Z]+)(?P<size>[a-z]*)|(r(?P<reg>[A-Z0-9]+)(?P<rsize>[a-z]*))")
|
||||||
|
@ -142,9 +163,9 @@ let {{
|
||||||
# modrm addressing.
|
# modrm addressing.
|
||||||
memEnv = copy.copy(env)
|
memEnv = copy.copy(env)
|
||||||
memEnv.doModRM = True
|
memEnv.doModRM = True
|
||||||
return doSplitDecode(specializeInst, "MODRM_MOD",
|
return doSplitDecode("MODRM_MOD",
|
||||||
{"3" : (Name + "_R", copy.copy(opTypes), regEnv)},
|
{"3" : (specializeInst, Name + "_R", copy.copy(opTypes), regEnv)},
|
||||||
(Name + "_M", copy.copy(opTypes), memEnv))
|
(doRipRelativeDecode, Name, copy.copy(opTypes), memEnv))
|
||||||
elif opType.tag in ("I", "J"):
|
elif opType.tag in ("I", "J"):
|
||||||
# Immediates
|
# Immediates
|
||||||
Name += "_I"
|
Name += "_I"
|
||||||
|
|
Loading…
Reference in a new issue