Merge zizzer.eecs.umich.edu:/bk/newmem

into  ahchoo.blinky.homelinux.org:/home/gblack/m5/newmem-x86

--HG--
extra : convert_revision : 1d2efac895a1c8328026a079e0b319a436325616
This commit is contained in:
Gabe Black 2007-06-12 17:19:14 +00:00
commit 02732929e8
22 changed files with 189 additions and 132 deletions

View file

@ -248,14 +248,14 @@ def template BlockMemConstructor {{
: %(base_class)s("%(mnemonic)s", machInst) : %(base_class)s("%(mnemonic)s", machInst)
{ {
%(constructor)s; %(constructor)s;
microOps[0] = new %(class_name)s_0(machInst); microops[0] = new %(class_name)s_0(machInst);
microOps[1] = new %(class_name)s_1(machInst); microops[1] = new %(class_name)s_1(machInst);
microOps[2] = new %(class_name)s_2(machInst); microops[2] = new %(class_name)s_2(machInst);
microOps[3] = new %(class_name)s_3(machInst); microops[3] = new %(class_name)s_3(machInst);
microOps[4] = new %(class_name)s_4(machInst); microops[4] = new %(class_name)s_4(machInst);
microOps[5] = new %(class_name)s_5(machInst); microops[5] = new %(class_name)s_5(machInst);
microOps[6] = new %(class_name)s_6(machInst); microops[6] = new %(class_name)s_6(machInst);
microOps[7] = new %(class_name)s_7(machInst); microops[7] = new %(class_name)s_7(machInst);
} }
}}; }};
@ -289,9 +289,9 @@ let {{
for microPc in range(8): for microPc in range(8):
flag_code = '' flag_code = ''
if (microPc == 7): if (microPc == 7):
flag_code = "flags[IsLastMicroOp] = true;" flag_code = "flags[IsLastMicroop] = true;"
elif (microPc == 0): elif (microPc == 0):
flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;" flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroop] = true;"
else: else:
flag_code = "flags[IsDelayedCommit] = true;" flag_code = "flags[IsDelayedCommit] = true;"
pcedCode = matcher.sub("Frd_%d" % microPc, code) pcedCode = matcher.sub("Frd_%d" % microPc, code)

View file

@ -58,33 +58,33 @@ output header {{
class SparcMacroInst : public SparcStaticInst class SparcMacroInst : public SparcStaticInst
{ {
protected: protected:
const uint32_t numMicroOps; const uint32_t numMicroops;
//Constructor. //Constructor.
SparcMacroInst(const char *mnem, ExtMachInst _machInst, SparcMacroInst(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, uint32_t _numMicroOps) OpClass __opClass, uint32_t _numMicroops)
: SparcStaticInst(mnem, _machInst, __opClass), : SparcStaticInst(mnem, _machInst, __opClass),
numMicroOps(_numMicroOps) numMicroops(_numMicroops)
{ {
assert(numMicroOps); assert(numMicroops);
microOps = new StaticInstPtr[numMicroOps]; microops = new StaticInstPtr[numMicroops];
flags[IsMacroOp] = true; flags[IsMacroop] = true;
} }
~SparcMacroInst() ~SparcMacroInst()
{ {
delete [] microOps; delete [] microops;
} }
std::string generateDisassembly(Addr pc, std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const; const SymbolTable *symtab) const;
StaticInstPtr * microOps; StaticInstPtr * microops;
StaticInstPtr fetchMicroOp(MicroPC microPC) StaticInstPtr fetchMicroop(MicroPC microPC)
{ {
assert(microPC < numMicroOps); assert(microPC < numMicroops);
return microOps[microPC]; return microops[microPC];
} }
%(MacroExecute)s %(MacroExecute)s
@ -100,7 +100,7 @@ output header {{
ExtMachInst _machInst, OpClass __opClass) ExtMachInst _machInst, OpClass __opClass)
: SparcStaticInst(mnem, _machInst, __opClass) : SparcStaticInst(mnem, _machInst, __opClass)
{ {
flags[IsMicroOp] = true; flags[IsMicroop] = true;
} }
}; };

View file

@ -87,6 +87,7 @@
#include "arch/x86/intregfile.hh" #include "arch/x86/intregfile.hh"
#include "base/misc.hh" #include "base/misc.hh"
#include "base/trace.hh"
#include "sim/serialize.hh" #include "sim/serialize.hh"
#include <string.h> #include <string.h>
@ -119,11 +120,13 @@ void IntRegFile::clear()
IntReg IntRegFile::readReg(int intReg) IntReg IntRegFile::readReg(int intReg)
{ {
DPRINTF(X86, "Read int reg %d and got value %#x\n", intReg, regs[intReg]);
return regs[intReg]; return regs[intReg];
} }
void IntRegFile::setReg(int intReg, const IntReg &val) void IntRegFile::setReg(int intReg, const IntReg &val)
{ {
DPRINTF(X86, "Setting int reg %d to value %#x\n", intReg, val);
regs[intReg] = val; regs[intReg] = val;
} }

View file

@ -58,9 +58,21 @@
// Bitfield definitions. // Bitfield definitions.
// //
//Prefixes //REX prefix
def bitfield REX rex; def bitfield REX rex;
def bitfield REX_W rex.w;
def bitfield REX_R rex.r;
def bitfield REX_X rex.x;
def bitfield REX_B rex.b;
//Legacy prefixes
def bitfield LEGACY legacy; def bitfield LEGACY legacy;
def bitfield LEGACY_REPNE legacy.repne;
def bitfield LEGACY_REP legacy.rep;
def bitfield LEGACY_LOCK legacy.lock;
def bitfield LEGACY_ADDR legacy.addr;
def bitfield LEGACY_OP legacy.op;
def bitfield LEGACY_SEG legacy.seg;
// Pieces of the opcode // Pieces of the opcode
def bitfield OPCODE_NUM opcode.num; def bitfield OPCODE_NUM opcode.num;
@ -87,3 +99,4 @@ def bitfield SIB_INDEX sib.index;
def bitfield SIB_BASE sib.base; def bitfield SIB_BASE sib.base;
def bitfield OPSIZE opSize; def bitfield OPSIZE opSize;
def bitfield ADDRSIZE addrSize;

View file

@ -237,10 +237,10 @@
0x7: xchg_Ev_Gv(); 0x7: xchg_Ev_Gv();
} }
0x11: decode OPCODE_OP_BOTTOM3 { 0x11: decode OPCODE_OP_BOTTOM3 {
0x0: MOV(); 0x0: Inst::MOV(Eb,Gb);
0x1: MOV(); 0x1: Inst::MOV(Ev,Gv);
0x2: MOV(); 0x2: Inst::MOV(Gb,Eb);
0x3: MOV(); 0x3: Inst::MOV(Gv,Eb);
0x4: mov_MwRv_Sw(); //What to do with this one? 0x4: mov_MwRv_Sw(); //What to do with this one?
0x5: lea_Gv_M(); 0x5: lea_Gv_M();
0x6: mov_Sw_MwRv(); 0x6: mov_Sw_MwRv();

View file

@ -62,12 +62,16 @@
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
def format Inst(*opTypeSet) {{ def format Inst(*opTypeSet) {{
decode_block = specializeInst(Name, list(opTypeSet), EmulEnv()) blocks = specializeInst(Name, list(opTypeSet), EmulEnv())
(header_output, decoder_output,
decode_block, exec_output) = blocks.makeList()
}}; }};
def format MultiInst(switchVal, *opTypeSets) {{ def format MultiInst(switchVal, *opTypeSets) {{
switcher = {} switcher = {}
for (count, opTypeSet) in zip(xrange(len(opTypeSets)), opTypeSets): for (count, opTypeSet) in zip(xrange(len(opTypeSets)), opTypeSets):
switcher[count] = (opTypeSet, EmulEnv()) switcher[count] = (opTypeSet, EmulEnv())
decode_block = doSplitDecode(Name, specializeInst, switchVal, switcher) blocks = doSplitDecode(Name, specializeInst, switchVal, switcher)
(header_output, decoder_output,
decode_block, exec_output) = blocks.makeList()
}}; }};

View file

@ -108,8 +108,6 @@ output header {{
output decoder {{ output decoder {{
namespace X86Macroop {
};
#include "base/cprintf.hh" #include "base/cprintf.hh"
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "cpu/thread_context.hh" // for Jump::branchTarget() #include "cpu/thread_context.hh" // for Jump::branchTarget()

View file

@ -53,7 +53,11 @@
# #
# Authors: Gabe Black # Authors: Gabe Black
microcode = "" microcode = '''
def macroop MOV{
mov "env.reg", "env.reg", "env.regm"
};
'''
#let {{ #let {{
# class MOV(Inst): # class MOV(Inst):
# "Mov ^0 ^0 ^1" # "Mov ^0 ^0 ^1"

View file

@ -72,33 +72,33 @@ def template MacroExecPanic {{
output header {{ output header {{
// Base class for combinationally generated macroops // Base class for combinationally generated macroops
class MacroOp : public StaticInst class Macroop : public StaticInst
{ {
protected: protected:
const uint32_t numMicroOps; const uint32_t numMicroops;
//Constructor. //Constructor.
MacroOp(const char *mnem, ExtMachInst _machInst, Macroop(const char *mnem, ExtMachInst _machInst,
uint32_t _numMicroOps) uint32_t _numMicroops)
: StaticInst(mnem, _machInst, No_OpClass), : StaticInst(mnem, _machInst, No_OpClass),
numMicroOps(_numMicroOps) numMicroops(_numMicroops)
{ {
assert(numMicroOps); assert(numMicroops);
microOps = new StaticInstPtr[numMicroOps]; microops = new StaticInstPtr[numMicroops];
flags[IsMacroOp] = true; flags[IsMacroop] = true;
} }
~MacroOp() ~Macroop()
{ {
delete [] microOps; delete [] microops;
} }
StaticInstPtr * microOps; StaticInstPtr * microops;
StaticInstPtr fetchMicroOp(MicroPC microPC) StaticInstPtr fetchMicroop(MicroPC microPC)
{ {
assert(microPC < numMicroOps); assert(microPC < numMicroops);
return microOps[microPC]; return microops[microPC];
} }
std::string generateDisassembly(Addr pc, std::string generateDisassembly(Addr pc,
@ -113,7 +113,7 @@ output header {{
// Basic instruction class declaration template. // Basic instruction class declaration template.
def template MacroDeclare {{ def template MacroDeclare {{
namespace X86Microop namespace X86Macroop
{ {
/** /**
* Static instruction class for "%(mnemonic)s". * Static instruction class for "%(mnemonic)s".
@ -122,20 +122,20 @@ def template MacroDeclare {{
{ {
public: public:
// Constructor. // Constructor.
%(class_name)s(ExtMachInst machInst); %(class_name)s(ExtMachInst machInst, EmulEnv env);
}; };
}; };
}}; }};
// Basic instruction class constructor template. // Basic instruction class constructor template.
def template MacroConstructor {{ def template MacroConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst) inline X86Macroop::%(class_name)s::%(class_name)s(ExtMachInst machInst, EmulEnv env)
: %(base_class)s("%(mnemonic)s", machInst, %(num_micro_ops)s) : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s)
{ {
%(constructor)s; %(constructor)s;
//alloc_micro_ops is the code that sets up the microOps //alloc_microops is the code that sets up the microops
//array in the parent class. //array in the parent class.
%(alloc_micro_ops)s; %(alloc_microops)s;
} }
}}; }};
@ -153,7 +153,7 @@ let {{
} }
self.declared = False self.declared = False
def getAllocator(self, env): def getAllocator(self, env):
return "new X86Macroop::%s(machInst)" % self.name return "new X86Macroop::%s(machInst, %s)" % (self.name, env.getAllocator())
def getDeclaration(self): def getDeclaration(self):
#FIXME This first parameter should be the mnemonic. I need to #FIXME This first parameter should be the mnemonic. I need to
#write some code which pulls that out #write some code which pulls that out
@ -167,14 +167,14 @@ let {{
micropc = 0 micropc = 0
for op in self.microops: for op in self.microops:
allocMicroops += \ allocMicroops += \
"microOps[%d] = %s;\n" % \ "microops[%d] = %s;\n" % \
(micropc, op.getAllocator(True, False, (micropc, op.getAllocator(True, False,
micropc == 0, micropc == 0,
micropc == numMicroops - 1)) micropc == numMicroops - 1))
micropc += 1 micropc += 1
iop = InstObjParams(self.name, self.name, "Macroop", iop = InstObjParams(self.name, self.name, "Macroop",
{"code" : "", "num_micro_ops" : numMicroops, {"code" : "", "num_microops" : numMicroops,
"alloc_micro_ops" : allocMicroops}) "alloc_microops" : allocMicroops})
return MacroConstructor.subst(iop); return MacroConstructor.subst(iop);
}}; }};
@ -201,26 +201,46 @@ output header {{
let {{ let {{
class EmulEnv(object): class EmulEnv(object):
def __init__(self): def __init__(self):
self.reg = "Not specified" self.reg = "0"
self.regm = "Not specified" self.regUsed = False
self.regm = "0"
self.regmUsed = False
self.immediate = "IMMEDIATE" self.immediate = "IMMEDIATE"
self.displacement = "DISPLACEMENT" self.displacement = "DISPLACEMENT"
self.addressSize = "ADDRSIZE" self.addressSize = "ADDRSIZE"
self.dataSize = "OPSIZE" self.dataSize = "OPSIZE"
def getAllocator(self): def getAllocator(self):
return "EmulEmv(%(reg)s, %(regm)s, %(immediate)s, %(displacement)s, %(addressSize)s, %(dataSize)s)" % \ return '''EmulEnv(%(reg)s,
self.__dict__() %(regm)s,
%(immediate)s,
%(displacement)s,
%(addressSize)s,
%(dataSize)s)''' % \
self.__dict__
def addReg(self, reg):
print "Adding reg \"%s\"" % reg
if not self.regUsed:
print "Added as reg"
self.reg = reg
self.regUsed = True
elif not self.regmUsed:
print "Added as regm"
self.regm = reg
self.regmUsed = True
else:
raise Exception, "EmulEnv is out of register specialization spots."
}}; }};
let {{ let {{
def genMacroop(Name, env): def genMacroop(Name, env):
blocks = OutputBlocks()
if not macroopDict.has_key(Name): if not macroopDict.has_key(Name):
raise Exception, "Unrecognized instruction: %s" % Name raise Exception, "Unrecognized instruction: %s" % Name
macroop = macroopDict[Name] macroop = macroopDict[Name]
if not macroop.declared: if not macroop.declared:
global header_output blocks.header_output = macroop.getDeclaration()
global decoder_output blocks.decoder_output = macroop.getDefinition()
header_output = macroop.getDeclaration() macroop.declared = True
decoder_output = macroop.getDefinition() blocks.decode_block = "return %s;\n" % macroop.getAllocator(env)
return "return %s;\n" % macroop.getAllocator(env) return blocks
}}; }};

View file

@ -67,7 +67,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// //
// Namespace statement. Everything below this line will be in the // Namespace statement. Everything below this line will be in the
// SparcISAInst namespace. // X86ISAInst namespace.
// //
namespace X86ISA; namespace X86ISA;

View file

@ -64,14 +64,14 @@ let {{
//A class which is the base of all x86 micro ops. It provides a function to //A class which is the base of all x86 micro ops. It provides a function to
//set necessary flags appropriately. //set necessary flags appropriately.
output header {{ output header {{
class X86MicroOpBase : public X86StaticInst class X86MicroopBase : public X86StaticInst
{ {
protected: protected:
const char * instMnem; const char * instMnem;
uint8_t opSize; uint8_t opSize;
uint8_t addrSize; uint8_t addrSize;
X86MicroOpBase(ExtMachInst _machInst, X86MicroopBase(ExtMachInst _machInst,
const char *mnem, const char *_instMnem, const char *mnem, const char *_instMnem,
bool isMicro, bool isDelayed, bool isMicro, bool isDelayed,
bool isFirst, bool isLast, bool isFirst, bool isLast,
@ -79,10 +79,10 @@ output header {{
X86StaticInst(mnem, _machInst, __opClass), X86StaticInst(mnem, _machInst, __opClass),
instMnem(_instMnem) instMnem(_instMnem)
{ {
flags[IsMicroOp] = isMicro; flags[IsMicroop] = isMicro;
flags[IsDelayedCommit] = isDelayed; flags[IsDelayedCommit] = isDelayed;
flags[IsFirstMicroOp] = isFirst; flags[IsFirstMicroop] = isFirst;
flags[IsLastMicroOp] = isLast; flags[IsLastMicroop] = isLast;
} }
std::string generateDisassembly(Addr pc, std::string generateDisassembly(Addr pc,
@ -108,15 +108,19 @@ let {{
def __init__(self, name): def __init__(self, name):
self.name = name self.name = name
# This converts a python bool into a C++ bool
def cppBool(self, val):
if val:
return "true"
else:
return "false"
# This converts a list of python bools into # This converts a list of python bools into
# a comma seperated list of C++ bools. # a comma seperated list of C++ bools.
def microFlagsText(self, vals): def microFlagsText(self, vals):
text = "" text = ""
for val in vals: for val in vals:
if val: text += ", %s" % self.cppBool(val)
text += ", true"
else:
text += ", false"
return text return text
def getAllocator(self, mnemonic, *microFlags): def getAllocator(self, mnemonic, *microFlags):
@ -130,7 +134,7 @@ let {{
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
def template MicroLdStOpDeclare {{ def template MicroLdStOpDeclare {{
class %(class_name)s : public X86MicroOpBase class %(class_name)s : public X86MicroopBase
{ {
protected: protected:
const uint8_t scale; const uint8_t scale;

View file

@ -72,7 +72,7 @@ def template MicroLimmOpExecute {{
}}; }};
def template MicroLimmOpDeclare {{ def template MicroLimmOpDeclare {{
class %(class_name)s : public X86MicroOpBase class %(class_name)s : public X86MicroopBase
{ {
protected: protected:
const RegIndex dest; const RegIndex dest;
@ -141,7 +141,7 @@ let {{
let {{ let {{
# Build up the all register version of this micro op # Build up the all register version of this micro op
iop = InstObjParams("limm", "Limm", 'X86MicroOpBase', iop = InstObjParams("limm", "Limm", 'X86MicroopBase',
{"code" : "DestReg = imm;"}) {"code" : "DestReg = imm;"})
header_output += MicroLimmOpDeclare.subst(iop) header_output += MicroLimmOpDeclare.subst(iop)
decoder_output += MicroLimmOpConstructor.subst(iop) decoder_output += MicroLimmOpConstructor.subst(iop)

View file

@ -231,17 +231,18 @@ let {{
self.ext = 0 self.ext = 0
def getAllocator(self, *microFlags): def getAllocator(self, *microFlags):
allocator = '''new %(class_name)s(machInst, %(mnemonic)s, allocator = '''new %(class_name)s(machInst, "%(mnemonic)s"
%(flags)s %(src1)s, %(src2)s, %(dest)s, %(flags)s, %(src1)s, %(src2)s, %(dest)s,
%(setStatus)s, %(dataSize)s, %(ext)s)''' % { %(setStatus)s, %(dataSize)s, %(ext)s)''' % {
"class_name" : self.className, "class_name" : self.className,
"mnemonic" : self.mnemonic, "mnemonic" : self.mnemonic,
"flags" : self.microFlagsText(microFlags), "flags" : self.microFlagsText(microFlags),
"src1" : self.src1, "src2" : self.src2, "src1" : self.src1, "src2" : self.src2,
"dest" : self.dest, "dest" : self.dest,
"setStatus" : self.setStatus, "setStatus" : self.cppBool(self.setStatus),
"dataSize" : self.dataSize, "dataSize" : self.dataSize,
"ext" : self.ext} "ext" : self.ext}
return allocator
class RegOpImm(X86Microop): class RegOpImm(X86Microop):
def __init__(self, dest, src1, imm): def __init__(self, dest, src1, imm):
@ -253,17 +254,18 @@ let {{
self.ext = 0 self.ext = 0
def getAllocator(self, *microFlags): def getAllocator(self, *microFlags):
allocator = '''new %(class_name)s(machInst, %(mnemonic)s, allocator = '''new %(class_name)s(machInst, "%(mnemonic)s"
%(flags)s %(src1)s, %(imm8)s, %(dest)s, %(flags)s, %(src1)s, %(imm8)s, %(dest)s,
%(setStatus)s, %(dataSize)s, %(ext)s)''' % { %(setStatus)s, %(dataSize)s, %(ext)s)''' % {
"class_name" : self.className, "class_name" : self.className,
"mnemonic" : self.mnemonic, "mnemonic" : self.mnemonic,
"flags" : self.microFlagsText(microFlags), "flags" : self.microFlagsText(microFlags),
"src1" : self.src1, "imm8" : self.imm8, "src1" : self.src1, "imm8" : self.imm8,
"dest" : self.dest, "dest" : self.dest,
"setStatus" : self.setStatus, "setStatus" : self.cppBool(self.setStatus),
"dataSize" : self.dataSize, "dataSize" : self.dataSize,
"ext" : self.ext} "ext" : self.ext}
return allocator
}}; }};
let {{ let {{
@ -290,7 +292,7 @@ let {{
immCode = matcher.sub("imm8", code) immCode = matcher.sub("imm8", code)
# Build up the all register version of this micro op # Build up the all register version of this micro op
iop = InstObjParams(name, Name, 'X86MicroOpBase', {"code" : regCode}) iop = InstObjParams(name, Name, 'X86MicroopBase', {"code" : regCode})
header_output += MicroRegOpDeclare.subst(iop) header_output += MicroRegOpDeclare.subst(iop)
decoder_output += MicroRegOpConstructor.subst(iop) decoder_output += MicroRegOpConstructor.subst(iop)
exec_output += MicroRegOpExecute.subst(iop) exec_output += MicroRegOpExecute.subst(iop)
@ -305,7 +307,7 @@ let {{
# Build up the immediate version of this micro op # Build up the immediate version of this micro op
iop = InstObjParams(name + "i", Name, iop = InstObjParams(name + "i", Name,
'X86MicroOpBase', {"code" : immCode}) 'X86MicroopBase', {"code" : immCode})
header_output += MicroRegOpImmDeclare.subst(iop) header_output += MicroRegOpImmDeclare.subst(iop)
decoder_output += MicroRegOpImmConstructor.subst(iop) decoder_output += MicroRegOpImmConstructor.subst(iop)
exec_output += MicroRegOpImmExecute.subst(iop) exec_output += MicroRegOpImmExecute.subst(iop)

View file

@ -69,7 +69,7 @@ def template MicroFaultExecute {{
}}; }};
def template MicroFaultDeclare {{ def template MicroFaultDeclare {{
class %(class_name)s : public X86MicroOpBase class %(class_name)s : public X86MicroopBase
{ {
protected: protected:
Fault fault; Fault fault;
@ -118,7 +118,7 @@ def template MicroFaultConstructor {{
let {{ let {{
# This microop takes in a single parameter, a fault to return. # This microop takes in a single parameter, a fault to return.
iop = InstObjParams("fault", "GenFault", 'X86MicroOpBase', {"code" : ""}) iop = InstObjParams("fault", "GenFault", 'X86MicroopBase', {"code" : ""})
header_output += MicroFaultDeclare.subst(iop) header_output += MicroFaultDeclare.subst(iop)
decoder_output += MicroFaultConstructor.subst(iop) decoder_output += MicroFaultConstructor.subst(iop)
exec_output += MicroFaultExecute.subst(iop) exec_output += MicroFaultExecute.subst(iop)

View file

@ -67,17 +67,20 @@ let {{
# builder is called on the exploded contents of "vals" values to generate # builder is called on the exploded contents of "vals" values to generate
# whatever code should be used. # whatever code should be used.
def doSplitDecode(Name, builder, switchVal, vals, default = None): def doSplitDecode(Name, builder, switchVal, vals, default = None):
decode_block = 'switch(%s) {\n' % switchVal blocks = OutputBlocks()
blocks.decode_block = 'switch(%s) {\n' % switchVal
for (val, todo) in vals.items(): for (val, todo) in vals.items():
new_block = builder(Name, *todo) new_blocks = builder(Name, *todo)
new_block = '\tcase %s: %s\n' % (val, new_block) new_blocks.decode_block = \
decode_block += new_block '\tcase %s: %s\n' % (val, new_blocks.decode_block)
blocks.append(new_blocks)
if default: if default:
new_block = builder(Name, *default) new_blocks = builder(Name, *default)
new_block = '\tdefault: %s\n' % new_block new_blocks.decode_block = \
decode_block += new_block '\tdefault: %s\n' % new_blocks.decode_block
decode_block += '}\n' blocks.append(new_blocks)
return decode_block blocks.decode_block += '}\n'
return blocks
}}; }};
let {{ let {{
@ -92,21 +95,24 @@ let {{
self.size = match.group("size") self.size = match.group("size")
self.rsize = match.group("rsize") self.rsize = match.group("rsize")
ModRMRegIndex = "(MODRM_REG | (REX_R << 3))"
ModRMRMIndex = "(MODRM_RM | (REX_B << 3))"
# This function specializes the given piece of code to use a particular # This function specializes the given piece of code to use a particular
# set of argument types described by "opTypes". # set of argument types described by "opTypes".
def specializeInst(Name, opTypes, env): def specializeInst(Name, opTypes, env):
print "Specializing %s with opTypes %s" % (Name, opTypes)
while len(opTypes): while len(opTypes):
# print "Building a composite op with tags", opTypes
# print "And code", code
opNum = len(opTypes) - 1
# Parse the operand type string we're working with # Parse the operand type string we're working with
opType = OpType(opTypes[opNum]) opType = OpType(opTypes[0])
if opType.reg: if opType.reg:
#Figure out what to do with fixed register operands #Figure out what to do with fixed register operands
#This is the index to use, so we should stick it some place. #This is the index to use, so we should stick it some place.
print "INTREG_R%s" % (opType.reg + opType.size.upper()) if opType.reg in ("A", "B", "C", "D"):
env.addReg("INTREG_R%sX" % opType.reg)
else:
env.addReg("INTREG_R%s" % opType.reg)
if opType.size: if opType.size:
if opType.rsize in ("l", "h", "b"): if opType.rsize in ("l", "h", "b"):
print "byte" print "byte"
@ -118,23 +124,23 @@ let {{
raise Exception, "Problem parsing operand tag: %s" % opType.tag raise Exception, "Problem parsing operand tag: %s" % opType.tag
elif opType.tag in ("C", "D", "G", "P", "S", "T", "V"): elif opType.tag in ("C", "D", "G", "P", "S", "T", "V"):
# Use the "reg" field of the ModRM byte to select the register # Use the "reg" field of the ModRM byte to select the register
print "(uint8_t)MODRM_REG" env.addReg(ModRMRegIndex)
elif opType.tag in ("E", "Q", "W"): elif opType.tag in ("E", "Q", "W"):
# This might refer to memory or to a register. We need to # This might refer to memory or to a register. We need to
# divide it up farther. # divide it up farther.
print "(uint8_t)MODRM_RM"
regTypes = copy.copy(opTypes) regTypes = copy.copy(opTypes)
regTypes.pop(0) regTypes.pop(0)
regEnv = copy.copy(env) regEnv = copy.copy(env)
regEnv.addReg(ModRMRMIndex)
# This needs to refer to memory, but we'll fill in the details # This needs to refer to memory, but we'll fill in the details
# later. It needs to take into account unaligned memory # later. It needs to take into account unaligned memory
# addresses. # addresses.
print "%0"
memTypes = copy.copy(opTypes) memTypes = copy.copy(opTypes)
memTypes.pop(0) memTypes.pop(0)
memEnv = copy.copy(env) memEnv = copy.copy(env)
print "%0"
return doSplitDecode(Name, specializeInst, "MODRM_MOD", return doSplitDecode(Name, specializeInst, "MODRM_MOD",
{"3" : (regTypes, memEnv)}, (memTypes, memEnv)) {"3" : (regTypes, regEnv)}, (memTypes, memEnv))
elif opType.tag in ("I", "J"): elif opType.tag in ("I", "J"):
# Immediates # Immediates
print "IMMEDIATE" print "IMMEDIATE"
@ -146,7 +152,7 @@ let {{
elif opType.tag in ("PR", "R", "VR"): elif opType.tag in ("PR", "R", "VR"):
# There should probably be a check here to verify that mod # There should probably be a check here to verify that mod
# is equal to 11b # is equal to 11b
print "(uint8_t)MODRM_RM" env.addReg(ModRMRMIndex)
else: else:
raise Exception, "Unrecognized tag %s." % opType.tag raise Exception, "Unrecognized tag %s." % opType.tag
opTypes.pop(0) opTypes.pop(0)

View file

@ -66,6 +66,8 @@ namespace X86ISA
{ {
origPC = basePC + offset; origPC = basePC + offset;
DPRINTF(Predecoder, "Setting origPC to %#x\n", origPC); DPRINTF(Predecoder, "Setting origPC to %#x\n", origPC);
emi.rex = 0;
emi.legacy = 0;
emi.opcode.num = 0; emi.opcode.num = 0;
immediateCollected = 0; immediateCollected = 0;

View file

@ -149,7 +149,8 @@ namespace X86ISA
//The effective operand size. //The effective operand size.
uint8_t opSize; uint8_t opSize;
//The //The effective address size.
uint8_t addrSize;
}; };
inline static std::ostream & inline static std::ostream &

View file

@ -162,7 +162,7 @@ Trace::InstRecord::dump()
static int fd = 0; static int fd = 0;
//Don't print what happens for each micro-op, just print out //Don't print what happens for each micro-op, just print out
//once at the last op, and for regular instructions. //once at the last op, and for regular instructions.
if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) if(!staticInst->isMicroop() || staticInst->isLastMicroop())
{ {
if(!cosim_listener) if(!cosim_listener)
{ {
@ -245,7 +245,7 @@ Trace::InstRecord::dump()
#if 0 //THE_ISA == SPARC_ISA #if 0 //THE_ISA == SPARC_ISA
//Don't print what happens for each micro-op, just print out //Don't print what happens for each micro-op, just print out
//once at the last op, and for regular instructions. //once at the last op, and for regular instructions.
if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) if(!staticInst->isMicroop() || staticInst->isLastMicroop())
{ {
static uint64_t regs[32] = { static uint64_t regs[32] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -432,7 +432,7 @@ Trace::InstRecord::dump()
setupSharedData(); setupSharedData();
// We took a trap on a micro-op... // We took a trap on a micro-op...
if (wasMicro && !staticInst->isMicroOp()) if (wasMicro && !staticInst->isMicroop())
{ {
// let's skip comparing this tick // let's skip comparing this tick
while (!compared) while (!compared)
@ -444,13 +444,13 @@ Trace::InstRecord::dump()
wasMicro = false; wasMicro = false;
} }
if (staticInst->isLastMicroOp()) if (staticInst->isLastMicroop())
wasMicro = false; wasMicro = false;
else if (staticInst->isMicroOp()) else if (staticInst->isMicroop())
wasMicro = true; wasMicro = true;
if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { if(!staticInst->isMicroop() || staticInst->isLastMicroop()) {
while (!compared) { while (!compared) {
if (shared_data->flags == OWN_M5) { if (shared_data->flags == OWN_M5) {
m5Pc = PC & TheISA::PAddrImplMask; m5Pc = PC & TheISA::PAddrImplMask;

View file

@ -540,8 +540,8 @@ AtomicSimpleCPU::tick()
} }
// @todo remove me after debugging with legion done // @todo remove me after debugging with legion done
if (curStaticInst && (!curStaticInst->isMicroOp() || if (curStaticInst && (!curStaticInst->isMicroop() ||
curStaticInst->isFirstMicroOp())) curStaticInst->isFirstMicroop()))
instCnt++; instCnt++;
if (simulate_stalls) { if (simulate_stalls) {

View file

@ -400,17 +400,17 @@ BaseSimpleCPU::preExecute()
//If we decoded an instruction and it's microcoded, start pulling //If we decoded an instruction and it's microcoded, start pulling
//out micro ops //out micro ops
if (instPtr && instPtr->isMacroOp()) { if (instPtr && instPtr->isMacroop()) {
curMacroStaticInst = instPtr; curMacroStaticInst = instPtr;
curStaticInst = curMacroStaticInst-> curStaticInst = curMacroStaticInst->
fetchMicroOp(thread->readMicroPC()); fetchMicroop(thread->readMicroPC());
} else { } else {
curStaticInst = instPtr; curStaticInst = instPtr;
} }
} else { } else {
//Read the next micro op from the macro op //Read the next micro op from the macro op
curStaticInst = curMacroStaticInst-> curStaticInst = curMacroStaticInst->
fetchMicroOp(thread->readMicroPC()); fetchMicroop(thread->readMicroPC());
} }
//If we decoded an instruction this "tick", record information about it. //If we decoded an instruction this "tick", record information about it.
@ -475,7 +475,7 @@ BaseSimpleCPU::advancePC(Fault fault)
thread->setNextMicroPC(1); thread->setNextMicroPC(1);
} else { } else {
//If we're at the last micro op for this instruction //If we're at the last micro op for this instruction
if (curStaticInst && curStaticInst->isLastMicroOp()) { if (curStaticInst && curStaticInst->isLastMicroop()) {
//We should be working with a macro op //We should be working with a macro op
assert(curMacroStaticInst); assert(curMacroStaticInst);
//Close out this macro op, and clean up the //Close out this macro op, and clean up the

View file

@ -76,9 +76,9 @@ StaticInst::hasBranchTarget(Addr pc, ThreadContext *tc, Addr &tgt) const
} }
StaticInstPtr StaticInstPtr
StaticInst::fetchMicroOp(MicroPC micropc) StaticInst::fetchMicroop(MicroPC micropc)
{ {
panic("StaticInst::fetchMicroOp() called on instruction " panic("StaticInst::fetchMicroop() called on instruction "
"that is not microcoded."); "that is not microcoded.");
} }

View file

@ -143,11 +143,11 @@ class StaticInstBase : public RefCounted
IsUnverifiable, ///< Can't be verified by a checker IsUnverifiable, ///< Can't be verified by a checker
//Flags for microcode //Flags for microcode
IsMacroOp, ///< Is a macroop containing microops IsMacroop, ///< Is a macroop containing microops
IsMicroOp, ///< Is a microop IsMicroop, ///< Is a microop
IsDelayedCommit, ///< This microop doesn't commit right away IsDelayedCommit, ///< This microop doesn't commit right away
IsLastMicroOp, ///< This microop ends a microop sequence IsLastMicroop, ///< This microop ends a microop sequence
IsFirstMicroOp, ///< This microop begins a microop sequence IsFirstMicroop, ///< This microop begins a microop sequence
//This flag doesn't do anything yet //This flag doesn't do anything yet
IsMicroBranch, ///< This microop branches within the microcode for a macroop IsMicroBranch, ///< This microop branches within the microcode for a macroop
@ -242,11 +242,11 @@ class StaticInstBase : public RefCounted
bool isQuiesce() const { return flags[IsQuiesce]; } bool isQuiesce() const { return flags[IsQuiesce]; }
bool isIprAccess() const { return flags[IsIprAccess]; } bool isIprAccess() const { return flags[IsIprAccess]; }
bool isUnverifiable() const { return flags[IsUnverifiable]; } bool isUnverifiable() const { return flags[IsUnverifiable]; }
bool isMacroOp() const { return flags[IsMacroOp]; } bool isMacroop() const { return flags[IsMacroop]; }
bool isMicroOp() const { return flags[IsMicroOp]; } bool isMicroop() const { return flags[IsMicroop]; }
bool isDelayedCommit() const { return flags[IsDelayedCommit]; } bool isDelayedCommit() const { return flags[IsDelayedCommit]; }
bool isLastMicroOp() const { return flags[IsLastMicroOp]; } bool isLastMicroop() const { return flags[IsLastMicroop]; }
bool isFirstMicroOp() const { return flags[IsFirstMicroOp]; } bool isFirstMicroop() const { return flags[IsFirstMicroop]; }
//This flag doesn't do anything yet //This flag doesn't do anything yet
bool isMicroBranch() const { return flags[IsMicroBranch]; } bool isMicroBranch() const { return flags[IsMicroBranch]; }
//@} //@}
@ -369,7 +369,7 @@ class StaticInst : public StaticInstBase
* Return the microop that goes with a particular micropc. This should * Return the microop that goes with a particular micropc. This should
* only be defined/used in macroops which will contain microops * only be defined/used in macroops which will contain microops
*/ */
virtual StaticInstPtr fetchMicroOp(MicroPC micropc); virtual StaticInstPtr fetchMicroop(MicroPC micropc);
/** /**
* Return the target address for a PC-relative branch. * Return the target address for a PC-relative branch.