diff options
-rw-r--r-- | src/arch/x86/isa/includes.isa | 1 | ||||
-rw-r--r-- | src/arch/x86/isa/macroop.isa | 20 | ||||
-rw-r--r-- | src/arch/x86/isa/microasm.isa | 10 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/base.isa | 30 | ||||
-rw-r--r-- | src/arch/x86/isa/rom.isa | 90 | ||||
-rw-r--r-- | src/arch/x86/microcode_rom.hh | 37 |
6 files changed, 181 insertions, 7 deletions
diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index 926e9185a..e523b7e32 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -113,6 +113,7 @@ output header {{ output decoder {{ #include "arch/x86/faults.hh" #include "arch/x86/floatregs.hh" +#include "arch/x86/microcode_rom.hh" #include "arch/x86/miscregs.hh" #include "arch/x86/segmentregs.hh" #include "base/cprintf.hh" diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa index 4818b926c..b851a92c7 100644 --- a/src/arch/x86/isa/macroop.isa +++ b/src/arch/x86/isa/macroop.isa @@ -76,12 +76,13 @@ output header {{ { protected: const uint32_t numMicroops; + X86ISA::EmulEnv emulEnv; //Constructor. Macroop(const char *mnem, ExtMachInst _machInst, - uint32_t _numMicroops) + uint32_t _numMicroops, X86ISA::EmulEnv _emulEnv) : StaticInst(mnem, _machInst, No_OpClass), - numMicroops(_numMicroops) + numMicroops(_numMicroops), emulEnv(_emulEnv) { assert(numMicroops); microops = new StaticInstPtr[numMicroops]; @@ -107,7 +108,20 @@ output header {{ return mnemonic; } + public: %(MacroExecPanic)s + + ExtMachInst + getExtMachInst() + { + return machInst; + } + + X86ISA::EmulEnv + getEmulEnv() + { + return emulEnv; + } }; }}; @@ -139,7 +153,7 @@ def template MacroDeclare {{ def template MacroConstructor {{ inline X86Macroop::%(class_name)s::%(class_name)s( ExtMachInst machInst, EmulEnv env) - : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s) + : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s, env) { %(adjust_env)s; %(adjust_imm)s; diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 735a7722c..9a5019f10 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -64,13 +64,16 @@ //Include code to build macroops in both C++ and python. ##include "macroop.isa" +//Include code to fill out the microcode ROM in both C++ and python. +##include "rom.isa" + let {{ import sys sys.path[0:0] = ["src/arch/x86/isa/"] from insts import microcode # print microcode - from micro_asm import MicroAssembler, Rom_Macroop, Rom - mainRom = Rom('main ROM') + from micro_asm import MicroAssembler, Rom_Macroop + mainRom = X86MicrocodeRom('main ROM') assembler = MicroAssembler(X86Macroop, microopClasses, mainRom, Rom_Macroop) # Add in symbols for the microcode registers for num in range(15): @@ -186,4 +189,7 @@ let {{ assembler.symbols["st"] = stack_index macroopDict = assembler.assemble(microcode) + + decoder_output += mainRom.getDefinition() + header_output += mainRom.getDeclaration() }}; diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa index 75658a26c..994e997d8 100644 --- a/src/arch/x86/isa/microops/base.isa +++ b/src/arch/x86/isa/microops/base.isa @@ -69,6 +69,28 @@ let {{ let {{ class X86Microop(object): + + generatorNameTemplate = "generate_%s_%d" + + generatorTemplate = ''' + StaticInstPtr + ''' + generatorNameTemplate + '''(StaticInstPtr curMacroop) + { + static const char * mnemonic = romMnemonic; + static const ExtMachInst dummyExtMachInst; + static const EmulEnv dummyEmulEnv(0, 0, 1, 1, 1); + + Macroop * macroop = dynamic_cast<Macroop *>(curMacroop.get()); + const ExtMachInst &machInst = + macroop ? macroop->getExtMachInst() : dummyExtMachInst; + const EmulEnv &env = + macroop ? macroop->getEmulEnv() : dummyEmulEnv; + // env may not be used in the microop's constructor. + RegIndex reg = env.reg; + reg = reg; + return %s; + } + ''' def __init__(self, name): self.name = name @@ -91,4 +113,12 @@ let {{ def getAllocator(self, mnemonic, *microFlags): return 'new %s(machInst, %s)' % \ (self.className, mnemonic, self.microFlagsText(microFlags)) + + def getGeneratorDef(self, micropc): + return self.generatorTemplate % \ + (self.className, micropc, \ + self.getAllocator(True, False, False, False)) + + def getGenerator(self, micropc): + return self.generatorNameTemplate % (self.className, micropc) }}; diff --git a/src/arch/x86/isa/rom.isa b/src/arch/x86/isa/rom.isa new file mode 100644 index 000000000..7d3eb8670 --- /dev/null +++ b/src/arch/x86/isa/rom.isa @@ -0,0 +1,90 @@ +// Copyright (c) 2008 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Gabe Black + +def template MicroRomConstructor {{ + + %(define_generators)s + const MicroPC X86ISA::MicrocodeRom::numMicroops = %(num_microops)s; + + X86ISA::MicrocodeRom::MicrocodeRom() + { + using namespace RomLabels; + genFuncs = new GenFunc[numMicroops]; + %(alloc_generators)s; + } +}}; + +let {{ + from micro_asm import Rom + + class X86MicrocodeRom(Rom): + def __init__(self, name): + super(X86MicrocodeRom, self).__init__(name) + self.directives = {} + + def add_microop(self, mnemonic, microop): + microop.mnemonic = mnemonic + microop.micropc = len(self.microops) + self.microops.append(microop) + + + def getDeclaration(self): + declareLabels = "namespace RomLabels {\n" + for (label, microop) in self.labels.items(): + declareLabels += "const static uint64_t label_%s = %d;\n" \ + % (label, microop.micropc) + for (label, microop) in self.externs.items(): + declareLabels += \ + "const static MicroPC extern_label_%s = %d;\n" \ + % (label, microop.micropc) + declareLabels += "}\n" + return declareLabels; + + def getDefinition(self): + numMicroops = len(self.microops) + allocGenerators = '' + micropc = 0 + define_generators = ''' + namespace + { + static const char romMnemonic[] = "Microcode_ROM"; + ''' + for op in self.microops: + define_generators += op.getGeneratorDef(micropc) + allocGenerators += "genFuncs[%d] = %s;\n" % \ + (micropc, op.getGenerator(micropc)) + micropc += 1 + define_generators += "}\n" + iop = InstObjParams(self.name, self.name, "MicrocodeRom", + {"code" : "", + "define_generators" : define_generators, + "num_microops" : numMicroops, + "alloc_generators" : allocGenerators + }) + return MicroRomConstructor.subst(iop); +}}; diff --git a/src/arch/x86/microcode_rom.hh b/src/arch/x86/microcode_rom.hh index 1495ff699..f8ad410ce 100644 --- a/src/arch/x86/microcode_rom.hh +++ b/src/arch/x86/microcode_rom.hh @@ -31,11 +31,44 @@ #ifndef __ARCH_X86_MICROCODE_ROM_HH__ #define __ARCH_X86_MICROCODE_ROM_HH__ -#include "sim/microcode_rom.hh" +#include "arch/x86/emulenv.hh" +#include "cpu/static_inst.hh" + +namespace X86ISAInst +{ + class MicrocodeRom + { + protected: + + typedef StaticInstPtr (*GenFunc)(StaticInstPtr); + + static const MicroPC numMicroops; + + GenFunc * genFuncs; + + public: + //Constructor. + MicrocodeRom(); + + //Destructor. + ~MicrocodeRom() + { + delete [] genFuncs; + } + + StaticInstPtr + fetchMicroop(MicroPC microPC, StaticInstPtr curMacroop) + { + microPC = normalMicroPC(microPC); + assert(microPC < numMicroops); + return genFuncs[microPC](curMacroop); + } + }; +} namespace X86ISA { - using ::MicrocodeRom; + using X86ISAInst::MicrocodeRom; } #endif // __ARCH_X86_MICROCODE_ROM_HH__ |