summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2008-10-12 17:48:44 -0700
committerGabe Black <gblack@eecs.umich.edu>2008-10-12 17:48:44 -0700
commite5f80924671bf0cfaf02c51f4b98d529631733f1 (patch)
tree1bdc1b3d0178e4648bbde6f4de378a20d295d027 /src/arch
parentc9ea0b73492bf116c836c54199898f29d9664bc0 (diff)
downloadgem5-e5f80924671bf0cfaf02c51f4b98d529631733f1.tar.xz
X86: Make X86's microcode ROM actually do something.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/isa/includes.isa1
-rw-r--r--src/arch/x86/isa/macroop.isa20
-rw-r--r--src/arch/x86/isa/microasm.isa10
-rw-r--r--src/arch/x86/isa/microops/base.isa30
-rw-r--r--src/arch/x86/isa/rom.isa90
-rw-r--r--src/arch/x86/microcode_rom.hh37
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__