diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-03-29 17:57:19 +0000 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-03-29 17:57:19 +0000 |
commit | 7fcc9d2106e1057f95867a5691c01b2c17278b31 (patch) | |
tree | 051a6fbc91295cfbd918e8857b92b6d253db023f /src/arch/x86 | |
parent | e67a207ad302e36fdfbb0a1eae0dadeef5b6a31d (diff) | |
download | gem5-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')
-rw-r--r-- | src/arch/x86/isa/decoder/one_byte_opcodes.isa | 2 | ||||
-rw-r--r-- | src/arch/x86/isa/formats/multi.isa | 82 |
2 files changed, 66 insertions, 18 deletions
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 0f030299a..b4aeece07 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -64,7 +64,7 @@ 0x6: push_ES(); 0x7: pop_ES(); default: MultiOp::add( - {{Add op0, op0, op1}}, + {{Add %0 %0 %1}}, OPCODE_OP_BOTTOM3, [[Eb,Gb],[Ev,Gv], [Gb,Eb],[Gv,Ev], 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 }}; |