diff options
Diffstat (limited to 'src/arch/x86/isa/macroop.isa')
-rw-r--r-- | src/arch/x86/isa/macroop.isa | 178 |
1 files changed, 131 insertions, 47 deletions
diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa index 663ec7aee..0cc818409 100644 --- a/src/arch/x86/isa/macroop.isa +++ b/src/arch/x86/isa/macroop.isa @@ -71,34 +71,34 @@ def template MacroExecPanic {{ output header {{ - // Base class for macroops - class MacroOp : public StaticInst + // Base class for combinationally generated macroops + class Macroop : public StaticInst { protected: - const uint32_t numMicroOps; + const uint32_t numMicroops; //Constructor. - MacroOp(const char *mnem, ExtMachInst _machInst, - uint32_t _numMicroOps) + Macroop(const char *mnem, ExtMachInst _machInst, + uint32_t _numMicroops) : StaticInst(mnem, _machInst, No_OpClass), - numMicroOps(_numMicroOps) + numMicroops(_numMicroops) { - assert(numMicroOps); - microOps = new StaticInstPtr[numMicroOps]; - flags[IsMacroOp] = true; + assert(numMicroops); + microops = new StaticInstPtr[numMicroops]; + flags[IsMacroop] = true; } - ~MacroOp() + ~Macroop() { - delete [] microOps; + delete [] microops; } - StaticInstPtr * microOps; + StaticInstPtr * microops; - StaticInstPtr fetchMicroOp(MicroPC microPC) + StaticInstPtr fetchMicroop(MicroPC microPC) { - assert(microPC < numMicroOps); - return microOps[microPC]; + assert(microPC < numMicroops); + return microops[microPC]; } std::string generateDisassembly(Addr pc, @@ -113,26 +113,30 @@ output header {{ // Basic instruction class declaration template. def template MacroDeclare {{ - /** - * Static instruction class for "%(mnemonic)s". - */ - class %(class_name)s : public %(base_class)s + namespace X86Macroop { - public: - // Constructor. - %(class_name)s(ExtMachInst machInst); + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + // Constructor. + %(class_name)s(ExtMachInst machInst, EmulEnv env); + }; }; }}; // Basic instruction class constructor template. def template MacroConstructor {{ - inline %(class_name)s::%(class_name)s(ExtMachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst, %(num_micro_ops)s) + inline X86Macroop::%(class_name)s::%(class_name)s(ExtMachInst machInst, EmulEnv env) + : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s) { - %(constructor)s; - //alloc_micro_ops is the code that sets up the microOps - //array in the parent class. - %(alloc_micro_ops)s; + %(adjust_env)s; + %(constructor)s; + //alloc_microops is the code that sets up the microops + //array in the parent class. + %(alloc_microops)s; } }}; @@ -142,23 +146,103 @@ def template MacroConstructor {{ // let {{ - def genMacroOp(name, Name, opSeq): - numMicroOps = len(opSeq) - allocMicroOps = '' - micropc = 0 - for op in opSeq: - allocMicroOps += \ - "microOps[%d] = %s;\n" % \ - (micropc, op.getAllocator('"' + name + '"', True, False, #op.delayed, - micropc == 0, - micropc == numMicroOps - 1)) - micropc += 1 - iop = InstObjParams(name, Name, 'MacroOp', - {'code' : '', 'num_micro_ops' : numMicroOps, - 'alloc_micro_ops' : allocMicroOps}) - header_output = MacroDeclare.subst(iop) - decoder_output = MacroConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = '' - return (header_output, decoder_output, decode_block, exec_output) + from micro_asm import Combinational_Macroop, Rom_Macroop + class X86Macroop(Combinational_Macroop): + def setAdjustEnv(self, val): + self.adjust_env = val + def __init__(self, name): + super(X86Macroop, self).__init__(name) + self.directives = { + "adjust_env" : self.setAdjustEnv + } + self.declared = False + self.adjust_env = "" + def getAllocator(self, env): + return "new X86Macroop::%s(machInst, %s)" % (self.name, env.getAllocator()) + def getDeclaration(self): + #FIXME This first parameter should be the mnemonic. I need to + #write some code which pulls that out + iop = InstObjParams(self.name, self.name, "Macroop", {"code" : ""}) + return MacroDeclare.subst(iop); + def getDefinition(self): + #FIXME This first parameter should be the mnemonic. I need to + #write some code which pulls that out + numMicroops = len(self.microops) + allocMicroops = '' + micropc = 0 + for op in self.microops: + allocMicroops += \ + "microops[%d] = %s;\n" % \ + (micropc, op.getAllocator(True, False, + micropc == 0, + micropc == numMicroops - 1)) + micropc += 1 + iop = InstObjParams(self.name, self.name, "Macroop", + {"code" : "", "num_microops" : numMicroops, + "alloc_microops" : allocMicroops, + "adjust_env" : self.adjust_env}) + return MacroConstructor.subst(iop); +}}; + +output header {{ + struct EmulEnv + { + X86ISA::RegIndex reg; + X86ISA::RegIndex regm; + uint8_t scale; + X86ISA::RegIndex index; + X86ISA::RegIndex base; + int dataSize; + int addressSize; + int stackSize; + + EmulEnv(X86ISA::RegIndex _reg, X86ISA::RegIndex _regm, + int _dataSize, int _addressSize, int _stackSize) : + reg(_reg), regm(_regm), + dataSize(_dataSize), addressSize(_addressSize), + stackSize(_stackSize) + {;} + }; +}}; + +let {{ + class EmulEnv(object): + def __init__(self): + self.reg = "0" + self.regUsed = False + self.regm = "0" + self.regmUsed = False + self.addressSize = "ADDRSIZE" + self.dataSize = "OPSIZE" + self.stackSize = "STACKSIZE" + def getAllocator(self): + return '''EmulEnv(%(reg)s, + %(regm)s, + %(dataSize)s, + %(addressSize)s, + %(stackSize)s)''' % \ + self.__dict__ + def addReg(self, reg): + if not self.regUsed: + self.reg = reg + self.regUsed = True + elif not self.regmUsed: + self.regm = reg + self.regmUsed = True + else: + raise Exception, "EmulEnv is out of register specialization spots." +}}; + +let {{ + def genMacroop(Name, env): + blocks = OutputBlocks() + if not macroopDict.has_key(Name): + raise Exception, "Unrecognized instruction: %s" % Name + macroop = macroopDict[Name] + if not macroop.declared: + blocks.header_output = macroop.getDeclaration() + blocks.decoder_output = macroop.getDefinition() + macroop.declared = True + blocks.decode_block = "return %s;\n" % macroop.getAllocator(env) + return blocks }}; |