From 7fcc9d2106e1057f95867a5691c01b2c17278b31 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 29 Mar 2007 17:57:19 +0000 Subject: 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 --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 2 +- src/arch/x86/isa/formats/multi.isa | 82 +++++++++++++++++++++------ 2 files changed, 66 insertions(+), 18 deletions(-) (limited to 'src') 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[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 }}; -- cgit v1.2.3