Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/56500 )
Change subject: arch,arch-x86: Set up explicit op types for macroops.
......................................................................
arch,arch-x86: Set up explicit op types for macroops.
By having the macroops explicitly declare what operand types they want,
this further modularizes them out of the main ISA description, and also
makes the disassembly more determinstically correct.
Change-Id: Id5b2a465851ba4920dfcfbb6336728253084bc24
---
M src/arch/x86/isa/macroop.isa
M src/arch/x86/isa/specialize.isa
M src/arch/x86/ucasmlib/arch/x86/macroop.py
3 files changed, 69 insertions(+), 44 deletions(-)
diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa
index 8331d94..f356fdd 100644
--- a/src/arch/x86/isa/macroop.isa
+++ b/src/arch/x86/isa/macroop.isa
@@ -48,17 +48,10 @@
self.dataSize = "OPSIZE"
self.stackSize = "STACKSIZE"
self.doModRM = False
- self.disassembly = ""
self.firstArgument = True
self.useStackSize = False
self.memoryInst = False
- def addToDisassembly(self, code):
- if not self.firstArgument:
- self.disassembly += "out << \", \";\n"
- self.firstArgument = False
- self.disassembly += code
-
def getAllocator(self):
if self.size == 'b':
self.dataSize = 1
diff --git a/src/arch/x86/isa/specialize.isa
b/src/arch/x86/isa/specialize.isa
index 58f2f72..a74dd92 100644
--- a/src/arch/x86/isa/specialize.isa
+++ b/src/arch/x86/isa/specialize.isa
@@ -68,14 +68,8 @@
env.memoryInst = True
norm_iter, rip_iter = itertools.tee(op_type_iter)
norm_env = copy.copy(env)
- norm_env.addToDisassembly(
- '''printMem(out, env.seg, env.scale, env.index, env.base,
- machInst.displacement, env.addressSize, false);''')
norm_blocks = specializeInst(Name + "_M", norm_iter, norm_env)
rip_env = copy.copy(env)
- rip_env.addToDisassembly(
- '''printMem(out, env.seg, 1, 0, 0,
- machInst.displacement, env.addressSize, true);''')
rip_blocks = specializeInst(Name + "_P", rip_iter, rip_env)
blocks = OutputBlocks()
@@ -142,9 +136,6 @@
reg_string = 'env.regm'
else:
reg_string = 'env.reg'
- env.addToDisassembly(
- 'printReg(out, RegId(IntRegClass, %s), regSize);\n' %
- reg_string)
Name += '_R'
@@ -154,17 +145,12 @@
reg_string = 'env.regm'
else:
reg_string = 'env.reg'
- env.addToDisassembly('printSegment(out, %s);\n' %
reg_string)
Name += '_S'
elif op_type.tag == 'B':
# This refers to registers whose index is encoded as part
of
# the opcode.
- env.addToDisassembly(
- 'printReg(out, RegId(IntRegClass, %s),
regSize);\n' %
- InstRegIndex)
-
Name += '_R'
env.addReg(InstRegIndex)
@@ -181,20 +167,14 @@
elif op_type.tag == 'C':
# A control register indexed by the 'reg' field
env.addReg(ModRMRegIndex)
- env.addToDisassembly(
- 'ccprintf(out, "CR%%d", %s);\n' % ModRMRegIndex)
Name += "_C"
elif op_type.tag == 'D':
# A debug register indexed by the 'reg' field
env.addReg(ModRMRegIndex)
- env.addToDisassembly(
- 'ccprintf(out, "DR%%d", %s);\n' % ModRMRegIndex)
Name += '_D'
elif op_type.tag == 'S':
# A segment selector register indexed by the 'reg' field
env.addReg(ModRMRegIndex)
- env.addToDisassembly(
- 'printSegment(out, %s);\n' % ModRMRegIndex)
Name += '_S'
elif op_type.tag in ('G', 'P', 'T', 'V'):
# Use the 'reg' field of the ModRM byte to select the
register
@@ -210,7 +190,6 @@
reg_format = \
'printReg(out, RegId(IntRegClass, %s), regSize);\n'
Name += '_R'
- env.addToDisassembly(reg_format % ModRMRegIndex)
elif op_type.tag in ('E', 'Q', 'W'):
# This might refer to memory or to a register. We need to
# divide it up farther.
@@ -232,7 +211,6 @@
reg_format = \
'printReg(out, RegId(IntRegClass, %s), regSize);\n'
reg_suffix = '_R'
- env.addToDisassembly(reg_format % ModRMRegIndex)
reg_iter, mem_iter = itertools.tee(op_type_iter)
return doSplitDecode('MODRM_MOD',
{'3' : specializeInst(
@@ -240,8 +218,6 @@
doRipRelativeDecode(Name, mem_iter, mem_env))
elif op_type.tag in ('I', 'J'):
# Immediates
- env.addToDisassembly(
- 'ccprintf(out, "%#x", machInst.immediate);\n')
Name += '_I'
elif op_type.tag == 'O':
# Immediate containing a memory offset
@@ -260,20 +236,9 @@
reg_format = \
'printReg(out, RegId(IntRegClass, %s), regSize);\n'
Name += '_R'
- env.addToDisassembly(reg_format % ModRMRegIndex)
elif op_type.tag in ('X', 'Y'):
# This type of memory addressing is for string
instructions.
# They'll use the right index and segment internally.
- if op_type.tag == 'X':
- env.addToDisassembly(
- '''printMem(out, env.seg,
- 1, X86ISA::NUM_INTREGS,
X86ISA::INTREG_RSI, 0,
- env.addressSize, false);''')
- else:
- env.addToDisassembly(
- '''printMem(out, SEGMENT_REG_ES,
- 1, X86ISA::NUM_INTREGS,
X86ISA::INTREG_RDI, 0,
- env.addressSize, false);''')
Name += ('_' + op_type.tag)
else:
raise Exception('Unrecognized tag {}.'.format(op_type.tag))
diff --git a/src/arch/x86/ucasmlib/arch/x86/macroop.py
b/src/arch/x86/ucasmlib/arch/x86/macroop.py
index 249d47e..d80c0cc 100644
--- a/src/arch/x86/ucasmlib/arch/x86/macroop.py
+++ b/src/arch/x86/ucasmlib/arch/x86/macroop.py
@@ -110,6 +110,58 @@
def control_indirect(self):
self.control_indirect = True
+ def set_args(self, *args):
+ reg_strings = ['env.reg', 'env.regm']
+ reg_iter = iter(reg_strings)
+ def next_reg():
+ try:
+ return next(reg_iter)
+ except StopIteration:
+ raise Exception('Ran out of register operands in '
+ 'sequence {args}')
+
+ for arg in args:
+
+ if arg == 'R':
+ code = f'printReg(out, RegId(IntRegClass, ' \
+ f'{next_reg()}), regSize);'
+ elif arg == 'X':
+ code = '''printMem(out, env.seg, 1, X86ISA::NUM_INTREGS,
+ X86ISA::INTREG_RSI, 0, env.addressSize,
+ false);'''
+ elif arg == 'Y':
+ code = '''printMem(out, SEGMENT_REG_ES, 1,
X86ISA::NUM_INTREGS,
+ X86ISA::INTREG_RDI, 0, env.addressSize,
+ false);'''
+ elif arg == 'M':
+ code = '''printMem(out, env.seg, env.scale, env.index,
+ env.base, machInst.displacement,
+ env.addressSize, false);'''
+ elif arg == 'P':
+ code = '''printMem(out, env.seg, env.scale, env.index,
+ env.base, machInst.displacement,
+ env.addressSize, true);'''
+ elif arg == 'S':
+ code = f'printSegment(out, {next_reg()});'
+ elif arg == 'C':
+ code = f'ccprintf(out, "CR%d", {next_reg()});'
+ elif arg == 'D':
+ code = f'ccprintf(out, "DR%d", {next_reg()});'
+ elif arg == 'MMX':
+ code = f'ccprintf(out, "MMX%d", {next_reg()});'
+ elif arg == 'XMM':
+ code = f'ccprintf(out, "XMM%d", {next_reg()});'
+ elif arg == 'I':
+ code = 'ccprintf(out, "%#x", machInst.immediate);'
+ elif arg == 'MI':
+ code = 'ccprintf(out, "%#x", machInst.immediate);'
+ else:
+ raise ValueError(f'Unrecognized arg type "{arg}"')
+
+ self.name += f'_{arg}'
+
+ self.disassembly.append(code)
+
def __init__(self, name):
super().__init__(name)
self.directives = {
@@ -121,8 +173,10 @@
"function_call" : self.function_call,
"function_return" : self.function_return,
"control_direct" : self.control_direct,
- "control_indirect" : self.control_indirect
+ "control_indirect" : self.control_indirect,
+ "args" : self.set_args
}
+ self.disassembly = []
self.declared = False
self.adjust_env = ""
self.init_env = ""
@@ -205,7 +259,7 @@
'adjust_env' : self.adjust_env,
'adjust_imm' : self.adjust_imm,
'adjust_disp' : self.adjust_disp,
- 'disassembly' : env.disassembly,
+ 'disassembly' : 'out << ", ";\n'.join(self.disassembly),
'reg_size' : reg_size,
'init_env' : self.initEnv
}
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/56500
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Id5b2a465851ba4920dfcfbb6336728253084bc24
Gerrit-Change-Number: 56500
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <gabe.bl...@gmail.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s