diff options
-rw-r--r-- | src/arch/x86/isa/formats/multi.isa | 4 | ||||
-rw-r--r-- | src/arch/x86/isa/macroop.isa | 51 | ||||
-rw-r--r-- | src/arch/x86/isa/microasm.isa | 21 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/base.isa | 49 | ||||
-rw-r--r-- | src/arch/x86/isa/specialize.isa | 38 |
5 files changed, 102 insertions, 61 deletions
diff --git a/src/arch/x86/isa/formats/multi.isa b/src/arch/x86/isa/formats/multi.isa index 7ad5ecd48..8f91c249c 100644 --- a/src/arch/x86/isa/formats/multi.isa +++ b/src/arch/x86/isa/formats/multi.isa @@ -72,7 +72,7 @@ def format Inst(*opTypeSet) {{ (header_output, decoder_output, decode_block, - exec_output) = doInst(name, Name, list(opTypeSet)) + exce_output) = doInst(name, Name, list(opTypeSet)).makeList() }}; def format MultiInst(switchVal, *opTypeSets) {{ @@ -82,5 +82,5 @@ def format MultiInst(switchVal, *opTypeSets) {{ (header_output, decoder_output, decode_block, - exec_output) = doSplitDecode(name, Name, doInst, switchVal, switcher) + exec_output) = doSplitDecode(name, Name, doInst, switchVal, switcher).makeList() }}; diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa index 7d41a2dea..663ec7aee 100644 --- a/src/arch/x86/isa/macroop.isa +++ b/src/arch/x86/isa/macroop.isa @@ -55,26 +55,30 @@ // // Authors: Gabe Black +////////////////////////////////////////////////////////////////////////////// +// +// Architecture independent +// + // Execute method for macroops. def template MacroExecPanic {{ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const { panic("Tried to execute macroop directly!"); - M5_DUMMY_RETURN + return NoFault; } }}; output header {{ - // Base class for most macroops, except ones that need to commit as - // they go. - class X86MacroInst : public StaticInst + // Base class for macroops + class MacroOp : public StaticInst { protected: const uint32_t numMicroOps; //Constructor. - X86MacroInst(const char *mnem, ExtMachInst _machInst, + MacroOp(const char *mnem, ExtMachInst _machInst, uint32_t _numMicroOps) : StaticInst(mnem, _machInst, No_OpClass), numMicroOps(_numMicroOps) @@ -84,7 +88,7 @@ output header {{ flags[IsMacroOp] = true; } - ~X86MacroInst() + ~MacroOp() { delete [] microOps; } @@ -97,10 +101,29 @@ output header {{ return microOps[microPC]; } + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return mnemonic; + } + %(MacroExecPanic)s }; }}; +// Basic instruction class declaration template. +def template MacroDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + // Constructor. + %(class_name)s(ExtMachInst machInst); + }; +}}; + // Basic instruction class constructor template. def template MacroConstructor {{ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) @@ -113,23 +136,27 @@ def template MacroConstructor {{ } }}; +////////////////////////////////////////////////////////////////////////////// +// +// X86 specific +// + let {{ def genMacroOp(name, Name, opSeq): - baseClass = 'X86MacroInst' - numMicroOps = len(opSeq.ops) + numMicroOps = len(opSeq) allocMicroOps = '' micropc = 0 - for op in opSeq.ops: + for op in opSeq: allocMicroOps += \ "microOps[%d] = %s;\n" % \ - (micropc, op.getAllocator(True, op.delayed, + (micropc, op.getAllocator('"' + name + '"', True, False, #op.delayed, micropc == 0, micropc == numMicroOps - 1)) micropc += 1 - iop = InstObjParams(name, Name, baseClass, + iop = InstObjParams(name, Name, 'MacroOp', {'code' : '', 'num_micro_ops' : numMicroOps, 'alloc_micro_ops' : allocMicroOps}) - header_output = BasicDeclare.subst(iop) + header_output = MacroDeclare.subst(iop) decoder_output = MacroConstructor.subst(iop) decode_block = BasicDecode.subst(iop) exec_output = '' diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 23567aae9..9d21b6bcc 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -85,7 +85,7 @@ let {{ text += ", false" return text - def getAllocator(self, *microFlags): + def getAllocator(self, mnemonic, *microFlags): args = '' signature = "<" emptySig = True @@ -104,7 +104,7 @@ let {{ else: raise Exception, "Unrecognized operand type." signature += ">" - return 'new %s%s(machInst%s%s)' % (self.className, signature, self.microFlagsText(microFlags), args) + return 'new %s%s(machInst, %s%s%s)' % (self.className, signature, mnemonic, self.microFlagsText(microFlags), args) }}; let{{ @@ -123,7 +123,7 @@ let{{ # the beginning of the line, so the previous component is stripped # before continuing. labelRe = re.compile(r'^[ \t]*(?P<label>\w\w*)[ \t]:') - lineRe = re.compile(r'^(?P<line>[^\n][^\n]*)$') + lineRe = re.compile(r'^(?P<line>..*)(\n|$)') classRe = re.compile(r'^[ \t]*(?P<className>[a-zA-Z_]\w*)') # This recognizes three different flavors of operands: # 1. Raw decimal numbers composed of digits between 0 and 9 @@ -145,14 +145,14 @@ let{{ # Get a line and seperate it from the rest of the code line = lineMatch.group("line") orig_line = line - # print "Parsing line %s" % line + #print "Parsing line %s" % line code = lineRe.sub('', code, 1) # Find the label, if any labelMatch = labelRe.search(line) if labelMatch != None: statement.label = labelMatch.group("label") - # print "Found label %s." % statement.label + #print "Found label %s." % statement.label # Clear the label from the statement line = labelRe.sub('', line, 1) @@ -163,7 +163,7 @@ let{{ % orig_line else: statement.className = classMatch.group("className") - # print "Found class name %s." % statement.className + #print "Found class name %s." % statement.className # Clear the class name from the statement line = classRe.sub('', line, 1) @@ -185,9 +185,9 @@ let{{ print "Problem parsing operand in statement: %s" \ % orig_line line = opRe.sub('', line, 1) - # print "Found operand %s." % statement.args[-1] + #print "Found operand %s." % statement.args[-1] opMatch = opRe.search(line) - # print "Found operands", statement.args + #print "Found operands", statement.args # Add this statement to our collection statements.append(statement) @@ -215,11 +215,14 @@ let{{ arg["operandImm"] = labels[arg["operandLabel"]] - micropc - 1 micropc += 1 + if len(statements) == 0: + raise Exception, "Didn't find any microops in microcode: \n%s" % orig_code + # If we can implement this instruction with exactly one microop, just # use that directly. if len(statements) == 1: decode_block = "return %s;" % \ - statements[0].getAllocator() + statements[0].getAllocator('"' + name + '"') return ('', '', decode_block, '') else: # Build a macroop to contain the sequence of microops we've diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa index 4254994f3..f0aab7872 100644 --- a/src/arch/x86/isa/microops/base.isa +++ b/src/arch/x86/isa/microops/base.isa @@ -69,20 +69,33 @@ output header {{ class X86MicroOpBase : public X86StaticInst { protected: + const char * instMnem; uint8_t opSize; uint8_t addrSize; - X86MicroOpBase(bool isMicro, bool isDelayed, + X86MicroOpBase(ExtMachInst _machInst, + const char *mnem, const char *_instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, - const char *mnem, ExtMachInst _machInst, OpClass __opClass) : - X86StaticInst(mnem, _machInst, __opClass) + X86StaticInst(mnem, _machInst, __opClass), + instMnem(_instMnem) { flags[IsMicroOp] = isMicro; flags[IsDelayedCommit] = isDelayed; flags[IsFirstMicroOp] = isFirst; flags[IsLastMicroOp] = isLast; } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "\t%s.%s", instMnem, mnemonic); + + return ss.str(); + } }; }}; @@ -127,7 +140,7 @@ let {{ }}; // A tmeplate for building a specialized version of the microcode -// instruction which knows specifies which arguments it wants +// instruction which specifies which arguments it wants def template MicroOpDeclare {{ template<> class %(class_name)s%(signature)s : public X86MicroOpBase @@ -137,11 +150,15 @@ def template MicroOpDeclare {{ void buildMe(); public: - %(class_name)s(bool isMicro, bool isDelayed, - bool isFirst, bool isLast, - ExtMachInst _machInst %(param_arg_dec)s); + %(class_name)s(ExtMachInst _machInst, + const char * instMnem, + bool isMicro, bool isDelayed, + bool isFirst, bool isLast + %(param_arg_dec)s); - %(class_name)s(ExtMachInst _machInst %(param_arg_dec)s); + %(class_name)s(ExtMachInst _machInst, + const char * instMnem + %(param_arg_dec)s); %(BasicExecDeclare)s }; @@ -155,19 +172,21 @@ def template MicroOpConstructor {{ } inline %(class_name)s%(signature)s::%(class_name)s( - ExtMachInst machInst %(param_arg_dec)s) : - %(base_class)s(false, false, false, false, - "%(mnemonic)s", machInst, %(op_class)s) + ExtMachInst machInst, const char * instMnem + %(param_arg_dec)s) : + %(base_class)s(machInst, "%(mnemonic)s", instMnem, + false, false, false, false, %(op_class)s) %(param_init)s { buildMe(); } inline %(class_name)s%(signature)s::%(class_name)s( - bool isMicro, bool isDelayed, bool isFirst, bool isLast, - ExtMachInst machInst %(param_arg_dec)s) - : %(base_class)s(isMicro, isDelayed, isFirst, isLast, - "%(mnemonic)s", machInst, %(op_class)s) + ExtMachInst machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast + %(param_arg_dec)s) + : %(base_class)s(machInst, "%(mnemonic)s", instMnem, + isMicro, isDelayed, isFirst, isLast, %(op_class)s) %(param_init)s { buildMe(); diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa index 9cac09770..ff92c3551 100644 --- a/src/arch/x86/isa/specialize.isa +++ b/src/arch/x86/isa/specialize.isa @@ -67,30 +67,18 @@ let {{ # builder is called on the exploded contents of "vals" values to generate # whatever code should be used. def doSplitDecode(name, Name, builder, switchVal, vals, default = None): - header_output = '' - decoder_output = '' - decode_block = 'switch(%s) {\n' % switchVal - exec_output = '' + blocks = OutputBlocks() + blocks.decode_block += 'switch(%s) {\n' % switchVal for (val, todo) in vals.items(): - (new_header_output, - new_decoder_output, - new_decode_block, - new_exec_output) = builder(name, Name, *todo) - header_output += new_header_output - decoder_output += new_decoder_output - decode_block += '\tcase %s: %s\n' % (val, new_decode_block) - exec_output += new_exec_output + built = builder(name, Name, *todo) + built.decode_block = '\tcase %s: %s\n' % (val, built.decode_block) + blocks.append(built) if default: - (new_header_output, - new_decoder_output, - new_decode_block, - new_exec_output) = builder(name, Name, *default) - header_output += new_header_output - decoder_output += new_decoder_output - decode_block += '\tdefault: %s\n' % new_decode_block - exec_output += new_exec_output - decode_block += '}\n' - return (header_output, decoder_output, decode_block, exec_output) + built = builder(name, Name, *default) + built.decode_block = '\tdefault: %s\n' % built.decode_block + blocks.append(built) + blocks.decode_block += '}\n' + return blocks }}; let {{ @@ -143,6 +131,7 @@ let {{ # This needs to refer to memory, but we'll fill in the details # later. It needs to take into account unaligned memory # addresses. + code = "GenFault ${new UnimpInstFault}\n" + code memCode = opRe.sub("%0", code) memTypes = copy.copy(opTypes) memTypes.pop(-1) @@ -156,6 +145,7 @@ let {{ # This needs to refer to memory, but we'll fill in the details # later. It needs to take into account unaligned memory # addresses. + code = "GenFault ${new UnimpInstFault}\n" + code code = opRe.sub("%0", code) elif opType.tag in ("PR", "R", "VR"): # There should probably be a check here to verify that mod @@ -168,5 +158,7 @@ let {{ # At this point, we've built up "code" to have all the necessary extra # instructions needed to implement whatever types of operands were # specified. Now we'll assemble it it into a StaticInst. - return assembleMicro(name, Name, code) + blocks = OutputBlocks() + blocks.append(assembleMicro(name, Name, code)) + return blocks }}; |