summaryrefslogtreecommitdiff
path: root/src/arch/x86/isa/formats
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-03-29 17:57:19 +0000
committerGabe Black <gblack@eecs.umich.edu>2007-03-29 17:57:19 +0000
commit7fcc9d2106e1057f95867a5691c01b2c17278b31 (patch)
tree051a6fbc91295cfbd918e8857b92b6d253db023f /src/arch/x86/isa/formats
parente67a207ad302e36fdfbb0a1eae0dadeef5b6a31d (diff)
downloadgem5-7fcc9d2106e1057f95867a5691c01b2c17278b31.tar.xz
Made the MultiOp format do a little more. It now sets up single microop instructions to return an instance of the right class. The code to decode register numbers and generate loads and stores still needs to be added. Also, a syntax for specifying operands as sources, destinations, or both needs to be established. Multipl microop instructions are also not handled, pending real macroop generation support.
--HG-- extra : convert_revision : 1a0a4b36afce8255e23e3cdd7a85c1392dda5f72
Diffstat (limited to 'src/arch/x86/isa/formats')
-rw-r--r--src/arch/x86/isa/formats/multi.isa82
1 files changed, 65 insertions, 17 deletions
diff --git a/src/arch/x86/isa/formats/multi.isa b/src/arch/x86/isa/formats/multi.isa
index 3e80f9cfb..c14e80095 100644
--- a/src/arch/x86/isa/formats/multi.isa
+++ b/src/arch/x86/isa/formats/multi.isa
@@ -74,33 +74,81 @@ let {{
}};
def format MultiOp(code, switchVal, opTags, *opt_flags) {{
- # Loads and stores that bring in and write out values from the
- # instructions. These are determined by the input and output tags,
- # and the resulting instruction will have the right number of micro ops,
- # or could be implemented as an atomic macro op.
- instNames = []
+ # These are C++ statements to create each type of static int. Since we
+ # don't know what will be microcoded and what won't, we can't assume a
+ # particular set of arguments for the constructor.
+ instNew = []
+ orig_code = code
+ opRe = re.compile(r"%(?P<operandNum>[0-9]*)")
+ # Get all the labels out of the code and make a dict for them. We'll do
+ # this once since the position of labels shouldn't need to change at all.
+ ops = assembleMicro(code)
+ labels = buildLabelDict(ops)
for tagSet in opTags:
- loads = []
- stores = []
+ # A list of strings which either have the register number to use, or
+ # a piece of code for calculating it.
+ regNums = []
+ code = orig_code
+ # Build up a name for this instructions class using the argument
+ # types. Each variation will get its own name this way.
postfix = ''
for tag in tagSet:
postfix += '_' + tag
- gather_inputs = ''
- if len(loads) + len(stores) == 0:
- # If there are no loads or stores, make this a single instruction.
- iop = InstObjParams(name, Name + postfix, 'X86StaticInst',
- {"code": code, "gather_inputs": gather_inputs},
- opt_flags)
+
+ # Figure out what register indexes to use for each operand. This
+ # is where loads/stores could be set up. I need to distinguish
+ # between inputs and outputs.
+ # For right now, the indexes are just an increasing sequence
+ counter = 0
+ for tag in tagSet:
+ regNums.append("%d" % counter)
+ counter += 1
+
+ # Replace the placeholders %0, %1, etc., with the right register
+ # indexes.
+ opMatch = opRe.search(code)
+ while opMatch:
+ opNum = opMatch.group("operandNum")
+ opNum = int(opNum)
+ if opNum > len(regNums):
+ print "No operand type specified for operand %d!" % opNum
+ print "I should bail out here too!"
+ regNum = regNums[opNum]
+ code = opRe.sub(regNum, code, 1)
+ opMatch = opRe.search(code)
+
+ # All the loads which feed this instruction
+ loads = []
+ # All the ops that make up the instruction proper.
+ ops = assembleMicro(code)
+ # Get all the labels out and make a dict for them
+ # All the stores for this instruction's results
+ stores = []
+
+ # Various counts
+ numLoads = len(loads)
+ numOps = len(ops)
+ numStores = len(stores)
+ totalOps = numLoads + numOps + numStores
+ print "There are %d total ops" % totalOps
+
+ # If we can implement this instruction with exactly one microop, just
+ # use that directly.
+ newStmnt = ''
+ if totalOps == 1:
+ newStmnt = ops[0].getAllocator(labels)
else:
# Build up a macro op. We'll punt on this for now
pass
+ instNew.append(newStmnt)
+
decodeBlob = 'switch(%s) {\n' % switchVal
counter = 0
- for inst in instNames:
- decodeBlob += '%d: return (X86StaticInst *)(new %s(machInst));\n' % \
- (counter, inst)
+ for newStmnt in instNew:
+ decodeBlob += 'case %d: return (X86StaticInst *)(%s);\n' % \
+ (counter, newStmnt)
counter += 1
decodeBlob += '}\n'
- # decode_block = BasicDecodeWithMnemonic.subst(iop)
+ decode_block = decodeBlob
}};