summaryrefslogtreecommitdiff
path: root/src/arch/x86/isa/macroop.isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/isa/macroop.isa')
-rw-r--r--src/arch/x86/isa/macroop.isa178
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
}};