summaryrefslogtreecommitdiff
path: root/src/arch/x86/isa
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-04-10 17:25:15 +0000
committerGabe Black <gblack@eecs.umich.edu>2007-04-10 17:25:15 +0000
commit9f4ebf915608403715bfb349a8871d4316e4a0c9 (patch)
tree74a07c15aded996aea76c46abbd20be43d504003 /src/arch/x86/isa
parentd6f81e02b4dbe97d95cdf94ff251f096ca6468ba (diff)
downloadgem5-9f4ebf915608403715bfb349a8871d4316e4a0c9.tar.xz
Reworked x86 a bit
--HG-- extra : convert_revision : def1a30e54b59c718c451a631a1be6f8e787e843
Diffstat (limited to 'src/arch/x86/isa')
-rw-r--r--src/arch/x86/isa/formats/multi.isa4
-rw-r--r--src/arch/x86/isa/macroop.isa51
-rw-r--r--src/arch/x86/isa/microasm.isa21
-rw-r--r--src/arch/x86/isa/microops/base.isa49
-rw-r--r--src/arch/x86/isa/specialize.isa38
5 files changed, 102 insertions, 61 deletions
diff --git a/src/arch/x86/isa/formats/multi.isa b/src/arch/x86/isa/formats/multi.isa
index 7ad5ecd48..8f91c249c 100644
--- a/src/arch/x86/isa/formats/multi.isa
+++ b/src/arch/x86/isa/formats/multi.isa
@@ -72,7 +72,7 @@ def format Inst(*opTypeSet) {{
(header_output,
decoder_output,
decode_block,
- exec_output) = doInst(name, Name, list(opTypeSet))
+ exce_output) = doInst(name, Name, list(opTypeSet)).makeList()
}};
def format MultiInst(switchVal, *opTypeSets) {{
@@ -82,5 +82,5 @@ def format MultiInst(switchVal, *opTypeSets) {{
(header_output,
decoder_output,
decode_block,
- exec_output) = doSplitDecode(name, Name, doInst, switchVal, switcher)
+ exec_output) = doSplitDecode(name, Name, doInst, switchVal, switcher).makeList()
}};
diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa
index 7d41a2dea..663ec7aee 100644
--- a/src/arch/x86/isa/macroop.isa
+++ b/src/arch/x86/isa/macroop.isa
@@ -55,26 +55,30 @@
//
// Authors: Gabe Black
+//////////////////////////////////////////////////////////////////////////////
+//
+// Architecture independent
+//
+
// Execute method for macroops.
def template MacroExecPanic {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
panic("Tried to execute macroop directly!");
- M5_DUMMY_RETURN
+ return NoFault;
}
}};
output header {{
- // Base class for most macroops, except ones that need to commit as
- // they go.
- class X86MacroInst : public StaticInst
+ // Base class for macroops
+ class MacroOp : public StaticInst
{
protected:
const uint32_t numMicroOps;
//Constructor.
- X86MacroInst(const char *mnem, ExtMachInst _machInst,
+ MacroOp(const char *mnem, ExtMachInst _machInst,
uint32_t _numMicroOps)
: StaticInst(mnem, _machInst, No_OpClass),
numMicroOps(_numMicroOps)
@@ -84,7 +88,7 @@ output header {{
flags[IsMacroOp] = true;
}
- ~X86MacroInst()
+ ~MacroOp()
{
delete [] microOps;
}
@@ -97,10 +101,29 @@ output header {{
return microOps[microPC];
}
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return mnemonic;
+ }
+
%(MacroExecPanic)s
};
}};
+// Basic instruction class declaration template.
+def template MacroDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+ // Constructor.
+ %(class_name)s(ExtMachInst machInst);
+ };
+}};
+
// Basic instruction class constructor template.
def template MacroConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
@@ -113,23 +136,27 @@ def template MacroConstructor {{
}
}};
+//////////////////////////////////////////////////////////////////////////////
+//
+// X86 specific
+//
+
let {{
def genMacroOp(name, Name, opSeq):
- baseClass = 'X86MacroInst'
- numMicroOps = len(opSeq.ops)
+ numMicroOps = len(opSeq)
allocMicroOps = ''
micropc = 0
- for op in opSeq.ops:
+ for op in opSeq:
allocMicroOps += \
"microOps[%d] = %s;\n" % \
- (micropc, op.getAllocator(True, op.delayed,
+ (micropc, op.getAllocator('"' + name + '"', True, False, #op.delayed,
micropc == 0,
micropc == numMicroOps - 1))
micropc += 1
- iop = InstObjParams(name, Name, baseClass,
+ iop = InstObjParams(name, Name, 'MacroOp',
{'code' : '', 'num_micro_ops' : numMicroOps,
'alloc_micro_ops' : allocMicroOps})
- header_output = BasicDeclare.subst(iop)
+ header_output = MacroDeclare.subst(iop)
decoder_output = MacroConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = ''
diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa
index 23567aae9..9d21b6bcc 100644
--- a/src/arch/x86/isa/microasm.isa
+++ b/src/arch/x86/isa/microasm.isa
@@ -85,7 +85,7 @@ let {{
text += ", false"
return text
- def getAllocator(self, *microFlags):
+ def getAllocator(self, mnemonic, *microFlags):
args = ''
signature = "<"
emptySig = True
@@ -104,7 +104,7 @@ let {{
else:
raise Exception, "Unrecognized operand type."
signature += ">"
- return 'new %s%s(machInst%s%s)' % (self.className, signature, self.microFlagsText(microFlags), args)
+ return 'new %s%s(machInst, %s%s%s)' % (self.className, signature, mnemonic, self.microFlagsText(microFlags), args)
}};
let{{
@@ -123,7 +123,7 @@ let{{
# the beginning of the line, so the previous component is stripped
# before continuing.
labelRe = re.compile(r'^[ \t]*(?P<label>\w\w*)[ \t]:')
- lineRe = re.compile(r'^(?P<line>[^\n][^\n]*)$')
+ lineRe = re.compile(r'^(?P<line>..*)(\n|$)')
classRe = re.compile(r'^[ \t]*(?P<className>[a-zA-Z_]\w*)')
# This recognizes three different flavors of operands:
# 1. Raw decimal numbers composed of digits between 0 and 9
@@ -145,14 +145,14 @@ let{{
# Get a line and seperate it from the rest of the code
line = lineMatch.group("line")
orig_line = line
- # print "Parsing line %s" % line
+ #print "Parsing line %s" % line
code = lineRe.sub('', code, 1)
# Find the label, if any
labelMatch = labelRe.search(line)
if labelMatch != None:
statement.label = labelMatch.group("label")
- # print "Found label %s." % statement.label
+ #print "Found label %s." % statement.label
# Clear the label from the statement
line = labelRe.sub('', line, 1)
@@ -163,7 +163,7 @@ let{{
% orig_line
else:
statement.className = classMatch.group("className")
- # print "Found class name %s." % statement.className
+ #print "Found class name %s." % statement.className
# Clear the class name from the statement
line = classRe.sub('', line, 1)
@@ -185,9 +185,9 @@ let{{
print "Problem parsing operand in statement: %s" \
% orig_line
line = opRe.sub('', line, 1)
- # print "Found operand %s." % statement.args[-1]
+ #print "Found operand %s." % statement.args[-1]
opMatch = opRe.search(line)
- # print "Found operands", statement.args
+ #print "Found operands", statement.args
# Add this statement to our collection
statements.append(statement)
@@ -215,11 +215,14 @@ let{{
arg["operandImm"] = labels[arg["operandLabel"]] - micropc - 1
micropc += 1
+ if len(statements) == 0:
+ raise Exception, "Didn't find any microops in microcode: \n%s" % orig_code
+
# If we can implement this instruction with exactly one microop, just
# use that directly.
if len(statements) == 1:
decode_block = "return %s;" % \
- statements[0].getAllocator()
+ statements[0].getAllocator('"' + name + '"')
return ('', '', decode_block, '')
else:
# Build a macroop to contain the sequence of microops we've
diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa
index 4254994f3..f0aab7872 100644
--- a/src/arch/x86/isa/microops/base.isa
+++ b/src/arch/x86/isa/microops/base.isa
@@ -69,20 +69,33 @@ output header {{
class X86MicroOpBase : public X86StaticInst
{
protected:
+ const char * instMnem;
uint8_t opSize;
uint8_t addrSize;
- X86MicroOpBase(bool isMicro, bool isDelayed,
+ X86MicroOpBase(ExtMachInst _machInst,
+ const char *mnem, const char *_instMnem,
+ bool isMicro, bool isDelayed,
bool isFirst, bool isLast,
- const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
- X86StaticInst(mnem, _machInst, __opClass)
+ X86StaticInst(mnem, _machInst, __opClass),
+ instMnem(_instMnem)
{
flags[IsMicroOp] = isMicro;
flags[IsDelayedCommit] = isDelayed;
flags[IsFirstMicroOp] = isFirst;
flags[IsLastMicroOp] = isLast;
}
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "\t%s.%s", instMnem, mnemonic);
+
+ return ss.str();
+ }
};
}};
@@ -127,7 +140,7 @@ let {{
}};
// A tmeplate for building a specialized version of the microcode
-// instruction which knows specifies which arguments it wants
+// instruction which specifies which arguments it wants
def template MicroOpDeclare {{
template<>
class %(class_name)s%(signature)s : public X86MicroOpBase
@@ -137,11 +150,15 @@ def template MicroOpDeclare {{
void buildMe();
public:
- %(class_name)s(bool isMicro, bool isDelayed,
- bool isFirst, bool isLast,
- ExtMachInst _machInst %(param_arg_dec)s);
+ %(class_name)s(ExtMachInst _machInst,
+ const char * instMnem,
+ bool isMicro, bool isDelayed,
+ bool isFirst, bool isLast
+ %(param_arg_dec)s);
- %(class_name)s(ExtMachInst _machInst %(param_arg_dec)s);
+ %(class_name)s(ExtMachInst _machInst,
+ const char * instMnem
+ %(param_arg_dec)s);
%(BasicExecDeclare)s
};
@@ -155,19 +172,21 @@ def template MicroOpConstructor {{
}
inline %(class_name)s%(signature)s::%(class_name)s(
- ExtMachInst machInst %(param_arg_dec)s) :
- %(base_class)s(false, false, false, false,
- "%(mnemonic)s", machInst, %(op_class)s)
+ ExtMachInst machInst, const char * instMnem
+ %(param_arg_dec)s) :
+ %(base_class)s(machInst, "%(mnemonic)s", instMnem,
+ false, false, false, false, %(op_class)s)
%(param_init)s
{
buildMe();
}
inline %(class_name)s%(signature)s::%(class_name)s(
- bool isMicro, bool isDelayed, bool isFirst, bool isLast,
- ExtMachInst machInst %(param_arg_dec)s)
- : %(base_class)s(isMicro, isDelayed, isFirst, isLast,
- "%(mnemonic)s", machInst, %(op_class)s)
+ ExtMachInst machInst, const char * instMnem,
+ bool isMicro, bool isDelayed, bool isFirst, bool isLast
+ %(param_arg_dec)s)
+ : %(base_class)s(machInst, "%(mnemonic)s", instMnem,
+ isMicro, isDelayed, isFirst, isLast, %(op_class)s)
%(param_init)s
{
buildMe();
diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa
index 9cac09770..ff92c3551 100644
--- a/src/arch/x86/isa/specialize.isa
+++ b/src/arch/x86/isa/specialize.isa
@@ -67,30 +67,18 @@ let {{
# builder is called on the exploded contents of "vals" values to generate
# whatever code should be used.
def doSplitDecode(name, Name, builder, switchVal, vals, default = None):
- header_output = ''
- decoder_output = ''
- decode_block = 'switch(%s) {\n' % switchVal
- exec_output = ''
+ blocks = OutputBlocks()
+ blocks.decode_block += 'switch(%s) {\n' % switchVal
for (val, todo) in vals.items():
- (new_header_output,
- new_decoder_output,
- new_decode_block,
- new_exec_output) = builder(name, Name, *todo)
- header_output += new_header_output
- decoder_output += new_decoder_output
- decode_block += '\tcase %s: %s\n' % (val, new_decode_block)
- exec_output += new_exec_output
+ built = builder(name, Name, *todo)
+ built.decode_block = '\tcase %s: %s\n' % (val, built.decode_block)
+ blocks.append(built)
if default:
- (new_header_output,
- new_decoder_output,
- new_decode_block,
- new_exec_output) = builder(name, Name, *default)
- header_output += new_header_output
- decoder_output += new_decoder_output
- decode_block += '\tdefault: %s\n' % new_decode_block
- exec_output += new_exec_output
- decode_block += '}\n'
- return (header_output, decoder_output, decode_block, exec_output)
+ built = builder(name, Name, *default)
+ built.decode_block = '\tdefault: %s\n' % built.decode_block
+ blocks.append(built)
+ blocks.decode_block += '}\n'
+ return blocks
}};
let {{
@@ -143,6 +131,7 @@ let {{
# This needs to refer to memory, but we'll fill in the details
# later. It needs to take into account unaligned memory
# addresses.
+ code = "GenFault ${new UnimpInstFault}\n" + code
memCode = opRe.sub("%0", code)
memTypes = copy.copy(opTypes)
memTypes.pop(-1)
@@ -156,6 +145,7 @@ let {{
# This needs to refer to memory, but we'll fill in the details
# later. It needs to take into account unaligned memory
# addresses.
+ code = "GenFault ${new UnimpInstFault}\n" + code
code = opRe.sub("%0", code)
elif opType.tag in ("PR", "R", "VR"):
# There should probably be a check here to verify that mod
@@ -168,5 +158,7 @@ let {{
# At this point, we've built up "code" to have all the necessary extra
# instructions needed to implement whatever types of operands were
# specified. Now we'll assemble it it into a StaticInst.
- return assembleMicro(name, Name, code)
+ blocks = OutputBlocks()
+ blocks.append(assembleMicro(name, Name, code))
+ return blocks
}};