summaryrefslogtreecommitdiff
path: root/src/arch/sparc/isa/formats
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc/isa/formats')
-rw-r--r--src/arch/sparc/isa/formats/basic.isa17
-rw-r--r--src/arch/sparc/isa/formats/branch.isa6
-rw-r--r--src/arch/sparc/isa/formats/formats.isa62
-rw-r--r--src/arch/sparc/isa/formats/integerop.isa12
-rw-r--r--src/arch/sparc/isa/formats/mem/basicmem.isa (renamed from src/arch/sparc/isa/formats/mem.isa)117
-rw-r--r--src/arch/sparc/isa/formats/mem/blockmem.isa337
-rw-r--r--src/arch/sparc/isa/formats/mem/mem.isa45
-rw-r--r--src/arch/sparc/isa/formats/mem/util.isa226
-rw-r--r--src/arch/sparc/isa/formats/micro.isa103
-rw-r--r--src/arch/sparc/isa/formats/priv.isa4
-rw-r--r--src/arch/sparc/isa/formats/unimp.isa147
11 files changed, 1016 insertions, 60 deletions
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index 0a47a7ffe..a4c05387b 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -33,6 +33,14 @@ def template BasicExecDeclare {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
+// Definitions of execute methods that panic.
+def template BasicExecPanic {{
+ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
+ {
+ panic("Execute method called when it shouldn't!");
+ }
+}};
+
// Basic instruction class declaration template.
def template BasicDeclare {{
/**
@@ -42,14 +50,14 @@ def template BasicDeclare {{
{
public:
// Constructor.
- %(class_name)s(MachInst machInst);
+ %(class_name)s(ExtMachInst machInst);
%(BasicExecDeclare)s
};
}};
// Basic instruction class constructor template.
def template BasicConstructor {{
- inline %(class_name)s::%(class_name)s(MachInst machInst)
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
@@ -80,6 +88,11 @@ def template BasicDecode {{
return new %(class_name)s(machInst);
}};
+// Basic decode template, passing mnemonic in as string arg to constructor.
+def template BasicDecodeWithMnemonic {{
+ return new %(class_name)s("%(mnemonic)s", machInst);
+}};
+
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst',
diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa
index 2c206354b..5fb7ade2d 100644
--- a/src/arch/sparc/isa/formats/branch.isa
+++ b/src/arch/sparc/isa/formats/branch.isa
@@ -80,7 +80,7 @@ output header {{
OpClass __opClass) :
BranchDisp(mnem, _machInst, __opClass)
{
- disp = sign_ext(_machInst << 2, bits + 2);
+ disp = sext<bits + 2>((_machInst & mask(bits)) << 2);
}
};
@@ -95,7 +95,7 @@ output header {{
OpClass __opClass) :
BranchDisp(mnem, _machInst, __opClass)
{
- disp = sign_ext((D16HI << 16) | (D16LO << 2), 18);
+ disp = sext<18>((D16HI << 16) | (D16LO << 2));
}
};
@@ -108,7 +108,7 @@ output header {{
protected:
// Constructor
BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) :
- Branch(mnem, _machInst, __opClass), imm(sign_ext(SIMM13, 13))
+ Branch(mnem, _machInst, __opClass), imm(sext<13>(SIMM13))
{
}
diff --git a/src/arch/sparc/isa/formats/formats.isa b/src/arch/sparc/isa/formats/formats.isa
new file mode 100644
index 000000000..5b81a1ab1
--- /dev/null
+++ b/src/arch/sparc/isa/formats/formats.isa
@@ -0,0 +1,62 @@
+// Copyright (c) 2006 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
+
+//Include the basic format
+//Templates from this format are used later
+##include "basic.isa"
+
+//Include base classes for microcoding instructions
+##include "micro.isa"
+
+//Include the noop format
+##include "nop.isa"
+
+//Include the integerOp and integerOpCc format
+##include "integerop.isa"
+
+//Include the memory formats
+##include "mem/mem.isa"
+
+//Include the compare and swap format
+##include "cas.isa"
+
+//Include the trap format
+##include "trap.isa"
+
+//Include the unimplemented format
+##include "unimp.isa"
+
+//Include the "unknown" format
+##include "unknown.isa"
+
+//Include the priveleged mode format
+##include "priv.isa"
+
+//Include the branch format
+##include "branch.isa"
+
diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa
index 83c7e6958..4f8ebebcc 100644
--- a/src/arch/sparc/isa/formats/integerop.isa
+++ b/src/arch/sparc/isa/formats/integerop.isa
@@ -87,7 +87,7 @@ output header {{
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
- imm = sign_ext(SIMM10, 10);
+ imm = sext<10>(SIMM10);
}
};
@@ -102,7 +102,7 @@ output header {{
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
- imm = sign_ext(SIMM11, 11);
+ imm = sext<11>(SIMM11);
}
};
@@ -117,7 +117,7 @@ output header {{
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
- imm = sign_ext(SIMM13, 13);
+ imm = sext<13>(SIMM13);
}
};
@@ -264,13 +264,13 @@ let {{
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
iop = InstObjParams(name, Name, 'IntOp', code,
- opt_flags, ("cc_code", ccCode))
+ opt_flags, {"cc_code": ccCode})
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
- immCode, opt_flags, ("cc_code", ccCode))
+ immCode, opt_flags, {"cc_code": ccCode})
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
exec_output += IntOpExecute.subst(imm_iop)
@@ -341,7 +341,7 @@ def format IntOpCcRes(code, *opt_flags) {{
def format SetHi(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SetHi',
- code, opt_flags, ("cc_code", ''))
+ code, opt_flags, {"cc_code": ''})
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)
diff --git a/src/arch/sparc/isa/formats/mem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa
index 9011c1fc6..c13194d0f 100644
--- a/src/arch/sparc/isa/formats/mem.isa
+++ b/src/arch/sparc/isa/formats/mem/basicmem.isa
@@ -1,3 +1,32 @@
+// Copyright (c) 2006 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: Ali Saidi
+// Gabe Black
+
////////////////////////////////////////////////////////////////////
//
// Mem instructions
@@ -30,15 +59,13 @@ output header {{
// Constructor
MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
- Mem(mnem, _machInst, __opClass)
- {
- imm = sign_ext(SIMM13, 13);
- }
+ Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13))
+ {}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
- int32_t imm;
+ const int32_t imm;
};
}};
@@ -99,73 +126,69 @@ output decoder {{
}
}};
-def template MemExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData) const
+def template MemDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
{
- Fault fault = NoFault;
- Addr EA;
- %(op_decl)s;
- %(op_rd)s;
- %(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
- %(load)s;
- %(code)s;
-
- if(fault == NoFault)
- {
- %(store)s;
- //Write the resulting state to the execution context
- %(op_wb)s;
- }
+ public:
- return fault;
- }
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
}};
let {{
- # Leave memAccessFlags at 0 for now
- loadString = "xc->read(EA, (uint%(width)s_t&)Mem, 0);"
- storeString = "uint64_t write_result = 0; \
- xc->write((uint%(width)s_t)Mem, EA, 0, &write_result);"
-
- def doMemFormat(code, load, store, name, Name, opt_flags):
+ def doMemFormat(code, execute, faultCode, name, Name, opt_flags):
addrCalcReg = 'EA = Rs1 + Rs2;'
addrCalcImm = 'EA = Rs1 + imm;'
iop = InstObjParams(name, Name, 'Mem', code,
- opt_flags, ("ea_code", addrCalcReg),
- ("load", load), ("store", store))
- iop_imm = InstObjParams(name, Name + 'Imm', 'MemImm', code,
- opt_flags, ("ea_code", addrCalcImm),
- ("load", load), ("store", store))
- header_output = BasicDeclare.subst(iop) + BasicDeclare.subst(iop_imm)
+ opt_flags, {"fault_check": faultCode, "ea_code": addrCalcReg})
+ iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code,
+ opt_flags, {"fault_check": faultCode, "ea_code": addrCalcImm})
+ header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
decode_block = ROrImmDecode.subst(iop)
- exec_output = MemExecute.subst(iop) + MemExecute.subst(iop_imm)
+ exec_output = doSplitExecute(code, addrCalcReg, addrCalcImm, execute,
+ faultCode, name, name + "Imm", Name, Name + "Imm", opt_flags)
return (header_output, decoder_output, exec_output, decode_block)
}};
-def format Load(code, width, *opt_flags) {{
+def format LoadAlt(code, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
- decode_block) = doMemFormat(code,
- loadString % {"width":width}, '', name, Name, opt_flags)
+ decode_block) = doMemFormat(code, LoadExecute,
+ AlternateAsiPrivFaultCheck, name, Name, opt_flags)
}};
-def format Store(code, width, *opt_flags) {{
+def format StoreAlt(code, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
- decode_block) = doMemFormat(code, '',
- storeString % {"width":width}, name, Name, opt_flags)
+ decode_block) = doMemFormat(code, StoreExecute,
+ AlternateAsiPrivFaultCheck, name, Name, opt_flags)
+}};
+
+def format Load(code, *opt_flags) {{
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doMemFormat(code,
+ LoadExecute, '', name, Name, opt_flags)
}};
-def format LoadStore(code, width, *opt_flags) {{
+def format Store(code, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
- loadString % {"width":width}, storeString % {"width":width},
- name, Name, opt_flags)
+ StoreExecute, '', name, Name, opt_flags)
}};
diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa
new file mode 100644
index 000000000..93ad1b2b8
--- /dev/null
+++ b/src/arch/sparc/isa/formats/mem/blockmem.isa
@@ -0,0 +1,337 @@
+// Copyright (c) 2006 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: Ali Saidi
+// Gabe Black
+
+////////////////////////////////////////////////////////////////////
+//
+// Block Memory instructions
+//
+
+output header {{
+
+ class BlockMem : public SparcMacroInst
+ {
+ protected:
+
+ // Constructor
+ // We make the assumption that all block memory operations
+ // Will take 8 instructions to execute
+ BlockMem(const char *mnem, ExtMachInst _machInst) :
+ SparcMacroInst(mnem, _machInst, No_OpClass, 8)
+ {}
+ };
+
+ class BlockMemImm : public BlockMem
+ {
+ protected:
+
+ // Constructor
+ BlockMemImm(const char *mnem, ExtMachInst _machInst) :
+ BlockMem(mnem, _machInst)
+ {}
+ };
+
+ class BlockMemMicro : public SparcDelayedMicroInst
+ {
+ protected:
+
+ // Constructor
+ BlockMemMicro(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, int8_t _offset) :
+ SparcDelayedMicroInst(mnem, _machInst, __opClass),
+ offset(_offset)
+ {}
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ const int8_t offset;
+ };
+
+ class BlockMemImmMicro : public BlockMemMicro
+ {
+ protected:
+
+ // Constructor
+ BlockMemImmMicro(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, int8_t _offset) :
+ BlockMemMicro(mnem, _machInst, __opClass, _offset),
+ imm(sext<13>(SIMM13))
+ {}
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ const int32_t imm;
+ };
+}};
+
+output decoder {{
+ std::string BlockMemMicro::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+ bool load = flags[IsLoad];
+ bool save = flags[IsStore];
+
+ printMnemonic(response, mnemonic);
+ if(save)
+ {
+ printReg(response, _srcRegIdx[0]);
+ ccprintf(response, ", ");
+ }
+ ccprintf(response, "[ ");
+ printReg(response, _srcRegIdx[!save ? 0 : 1]);
+ ccprintf(response, " + ");
+ printReg(response, _srcRegIdx[!save ? 1 : 2]);
+ ccprintf(response, " ]");
+ if(load)
+ {
+ ccprintf(response, ", ");
+ printReg(response, _destRegIdx[0]);
+ }
+
+ return response.str();
+ }
+
+ std::string BlockMemImmMicro::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+ bool load = flags[IsLoad];
+ bool save = flags[IsStore];
+
+ printMnemonic(response, mnemonic);
+ if(save)
+ {
+ printReg(response, _srcRegIdx[1]);
+ ccprintf(response, ", ");
+ }
+ ccprintf(response, "[ ");
+ printReg(response, _srcRegIdx[0]);
+ if(imm >= 0)
+ ccprintf(response, " + 0x%x ]", imm);
+ else
+ ccprintf(response, " + -0x%x ]", -imm);
+ if(load)
+ {
+ ccprintf(response, ", ");
+ printReg(response, _destRegIdx[0]);
+ }
+
+ return response.str();
+ }
+
+}};
+
+def template BlockMemDeclare {{
+ /**
+ * Static instruction class for a block memory operation
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+ //Constructor
+ %(class_name)s(ExtMachInst machInst);
+
+ protected:
+ class %(class_name)s_0 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_0(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_1 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_1(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_2 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_2(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_3 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_3(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_4 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_4(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_5 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_5(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_6 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_6(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_7 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_7(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+ };
+}};
+
+// Basic instruction class constructor template.
+def template BlockMemConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst)
+ {
+ %(constructor)s;
+ microOps[0] = new %(class_name)s_0(machInst);
+ microOps[1] = new %(class_name)s_1(machInst);
+ microOps[2] = new %(class_name)s_2(machInst);
+ microOps[3] = new %(class_name)s_3(machInst);
+ microOps[4] = new %(class_name)s_4(machInst);
+ microOps[5] = new %(class_name)s_5(machInst);
+ microOps[6] = new %(class_name)s_6(machInst);
+ microOps[7] = new %(class_name)s_7(machInst);
+ }
+}};
+
+def template BlockMemMicroConstructor {{
+ inline %(class_name)s::
+ %(class_name)s_%(micro_pc)s::
+ %(class_name)s_%(micro_pc)s(ExtMachInst machInst) :
+ %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]",
+ machInst, %(op_class)s, %(micro_pc)s * 8)
+ {
+ %(constructor)s;
+ %(set_flags)s;
+ }
+}};
+
+let {{
+
+ def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags):
+ # XXX Need to take care of pstate.hpriv as well. The lower ASIs
+ # are split into ones that are available in priv and hpriv, and
+ # those that are only available in hpriv
+ addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
+ addrCalcImm = 'EA = Rs1 + imm + offset;'
+ iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
+ iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
+ header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
+ decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm)
+ decode_block = ROrImmDecode.subst(iop)
+ matcher = re.compile(r'Frd_N')
+ exec_output = ''
+ for microPc in range(8):
+ flag_code = ''
+ if (microPc == 7):
+ flag_code = "flags[IsLastMicroOp] = true;"
+ pcedCode = matcher.sub("Frd_%d" % microPc, code)
+ iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
+ opt_flags, {"ea_code": addrCalcReg,
+ "fault_check": faultCode, "micro_pc": microPc,
+ "set_flags": flag_code})
+ iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode,
+ opt_flags, {"ea_code": addrCalcImm,
+ "fault_check": faultCode, "micro_pc": microPc,
+ "set_flags": flag_code})
+ decoder_output += BlockMemMicroConstructor.subst(iop)
+ decoder_output += BlockMemMicroConstructor.subst(iop_imm)
+ exec_output += doSplitExecute(
+ pcedCode, addrCalcReg, addrCalcImm, execute, faultCode,
+ makeMicroName(name, microPc),
+ makeMicroName(name + "Imm", microPc),
+ makeMicroName(Name, microPc),
+ makeMicroName(Name + "Imm", microPc),
+ opt_flags);
+ faultCode = ''
+ return (header_output, decoder_output, exec_output, decode_block)
+}};
+
+def format BlockLoad(code, *opt_flags) {{
+ # We need to make sure to check the highest priority fault last.
+ # That way, if other faults have been detected, they'll be overwritten
+ # rather than the other way around.
+ faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doBlockMemFormat(code, faultCode,
+ LoadExecute, name, Name, opt_flags)
+}};
+
+def format BlockStore(code, *opt_flags) {{
+ # We need to make sure to check the highest priority fault last.
+ # That way, if other faults have been detected, they'll be overwritten
+ # rather than the other way around.
+ faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doBlockMemFormat(code, faultCode,
+ StoreExecute, name, Name, opt_flags)
+}};
diff --git a/src/arch/sparc/isa/formats/mem/mem.isa b/src/arch/sparc/isa/formats/mem/mem.isa
new file mode 100644
index 000000000..20a22c45d
--- /dev/null
+++ b/src/arch/sparc/isa/formats/mem/mem.isa
@@ -0,0 +1,45 @@
+// Copyright (c) 2006 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: Ali Saidi
+// Gabe Black
+
+////////////////////////////////////////////////////////////////////
+//
+// Mem formats
+//
+
+//Include mem utility templates and functions
+##include "util.isa"
+
+//Include the basic memory format
+##include "basicmem.isa"
+
+//Include the block memory format
+##include "blockmem.isa"
+
+//Include the load/store memory format
+##include "loadstore.isa"
diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa
new file mode 100644
index 000000000..241a25d17
--- /dev/null
+++ b/src/arch/sparc/isa/formats/mem/util.isa
@@ -0,0 +1,226 @@
+// Copyright (c) 2006 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: Ali Saidi
+// Gabe Black
+// Steve Reinhardt
+
+////////////////////////////////////////////////////////////////////
+//
+// Mem utility templates and functions
+//
+
+//This template provides the execute functions for a load
+def template LoadExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ Addr EA;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ %(fault_check)s;
+ if(fault == NoFault)
+ {
+ fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
+ }
+ if(fault == NoFault)
+ {
+ %(code)s;
+ }
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ Fault fault = NoFault;
+ Addr EA;
+ uint%(mem_acc_size)s_t Mem;
+ %(ea_decl)s;
+ %(ea_rd)s;
+ %(ea_code)s;
+ %(fault_check)s;
+ if(fault == NoFault)
+ {
+ fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
+ }
+ return fault;
+ }
+
+ Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ Fault fault = NoFault;
+ %(code_decl)s;
+ %(code_rd)s;
+ Mem = pkt->get<typeof(Mem)>();
+ %(code)s;
+ if(fault == NoFault)
+ {
+ %(code_wb)s;
+ }
+ return fault;
+ }
+}};
+
+//This template provides the execute functions for a store
+def template StoreExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ uint64_t write_result = 0;
+ Addr EA;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ %(fault_check)s;
+ if(fault == NoFault)
+ {
+ %(code)s;
+ }
+ if(fault == NoFault)
+ {
+ fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
+ }
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ Fault fault = NoFault;
+ uint64_t write_result = 0;
+ Addr EA;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ %(fault_check)s;
+ if(fault == NoFault)
+ {
+ %(code)s;
+ }
+ if(fault == NoFault)
+ {
+ fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
+ }
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+ return fault;
+ }
+
+ Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ return NoFault;
+ }
+}};
+
+//This delcares the initiateAcc function in memory operations
+def template InitiateAccDeclare {{
+ Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+//This declares the completeAcc function in memory operations
+def template CompleteAccDeclare {{
+ Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+//Here are some code snippets which check for various fault conditions
+let {{
+ # The LSB can be zero, since it's really the MSB in doubles and quads
+ # and we're dealing with doubles
+ BlockAlignmentFaultCheck = '''
+ if(RD & 0xe)
+ fault = new IllegalInstruction;
+ else if(EA & 0x3f)
+ fault = new MemAddressNotAligned;
+ '''
+ # XXX Need to take care of pstate.hpriv as well. The lower ASIs
+ # are split into ones that are available in priv and hpriv, and
+ # those that are only available in hpriv
+ AlternateASIPrivFaultCheck = '''
+ if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
+ fault = new PrivilegedAction;
+ else if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2))
+ fault = new PrivilegedAction;
+ '''
+
+}};
+
+//A simple function to generate the name of the macro op of a certain
+//instruction at a certain micropc
+let {{
+ def makeMicroName(name, microPc):
+ return name + "::" + name + "_" + str(microPc)
+}};
+
+//This function properly generates the execute functions for one of the
+//templates above. This is needed because in one case, ea computation,
+//fault checks and the actual code all occur in the same function,
+//and in the other they're distributed across two. Also note that for
+//execute functions, the name of the base class doesn't matter.
+let {{
+ def doSplitExecute(code, eaRegCode, eaImmCode, execute,
+ faultCode, nameReg, nameImm, NameReg, NameImm, opt_flags):
+ codeIop = InstObjParams(nameReg, NameReg, '', code, opt_flags)
+ executeCode = ''
+ for (eaCode, name, Name) in (
+ (eaRegCode, nameReg, NameReg),
+ (eaImmCode, nameImm, NameImm)):
+ eaIop = InstObjParams(name, Name, '', eaCode,
+ opt_flags, {"fault_check": faultCode})
+ iop = InstObjParams(name, Name, '', code, opt_flags,
+ {"fault_check": faultCode, "ea_code" : eaCode})
+ (iop.ea_decl,
+ iop.ea_rd,
+ iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb)
+ (iop.code_decl,
+ iop.code_rd,
+ iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
+ executeCode += execute.subst(iop)
+ return executeCode
+}};
diff --git a/src/arch/sparc/isa/formats/micro.isa b/src/arch/sparc/isa/formats/micro.isa
new file mode 100644
index 000000000..82d7fb4cb
--- /dev/null
+++ b/src/arch/sparc/isa/formats/micro.isa
@@ -0,0 +1,103 @@
+// Copyright (c) 2006 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
+
+output header {{
+
+ class SparcMacroInst : public SparcStaticInst
+ {
+ protected:
+ const uint32_t numMicroOps;
+
+ //Constructor.
+ SparcMacroInst(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, uint32_t _numMicroOps)
+ : SparcStaticInst(mnem, _machInst, __opClass),
+ numMicroOps(_numMicroOps)
+ {
+ assert(numMicroOps);
+ microOps = new StaticInstPtr[numMicroOps];
+ flags[IsMacroOp] = true;
+ }
+
+ ~SparcMacroInst()
+ {
+ delete [] microOps;
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ StaticInstPtr * microOps;
+
+ StaticInstPtr fetchMicroOp(MicroPC microPC)
+ {
+ assert(microPC < numMicroOps);
+ return microOps[microPC];
+ }
+
+ %(BasicExecPanic)s
+ };
+
+ class SparcMicroInst : public SparcStaticInst
+ {
+ protected:
+ //Constructor.
+ SparcMicroInst(const char *mnem,
+ ExtMachInst _machInst, OpClass __opClass)
+ : SparcStaticInst(mnem, _machInst, __opClass)
+ {
+ flags[IsMicroOp] = true;
+ }
+ };
+
+ class SparcDelayedMicroInst : public SparcMicroInst
+ {
+ protected:
+ //Constructor.
+ SparcDelayedMicroInst(const char *mnem,
+ ExtMachInst _machInst, OpClass __opClass)
+ : SparcMicroInst(mnem, _machInst, __opClass)
+ {
+ flags[IsDelayedCommit] = true;
+ }
+ };
+}};
+
+output decoder {{
+
+ std::string SparcMacroInst::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ return response.str();
+ }
+
+}};
diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa
index d7ee01519..2a38422a7 100644
--- a/src/arch/sparc/isa/formats/priv.isa
+++ b/src/arch/sparc/isa/formats/priv.isa
@@ -103,13 +103,13 @@ let {{
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
iop = InstObjParams(name, Name, 'Priv', code,
- opt_flags, ("check", checkCode))
+ opt_flags, {"check": checkCode})
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = PrivExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', 'PrivImm',
- immCode, opt_flags, ("check", checkCode))
+ immCode, opt_flags, {"check": checkCode})
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
exec_output += PrivExecute.subst(imm_iop)
diff --git a/src/arch/sparc/isa/formats/unimp.isa b/src/arch/sparc/isa/formats/unimp.isa
new file mode 100644
index 000000000..a623507a1
--- /dev/null
+++ b/src/arch/sparc/isa/formats/unimp.isa
@@ -0,0 +1,147 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2003-2005 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: Steve Reinhardt
+
+////////////////////////////////////////////////////////////////////
+//
+// Unimplemented instructions
+//
+
+output header {{
+ /**
+ * Static instruction class for unimplemented instructions that
+ * cause simulator termination. Note that these are recognized
+ * (legal) instructions that the simulator does not support; the
+ * 'Unknown' class is used for unrecognized/illegal instructions.
+ * This is a leaf class.
+ */
+ class FailUnimplemented : public SparcStaticInst
+ {
+ public:
+ /// Constructor
+ FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
+ : SparcStaticInst(_mnemonic, _machInst, No_OpClass)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for unimplemented instructions that cause a warning
+ * to be printed (but do not terminate simulation). This
+ * implementation is a little screwy in that it will print a
+ * warning for each instance of a particular unimplemented machine
+ * instruction, not just for each unimplemented opcode. Should
+ * probably make the 'warned' flag a static member of the derived
+ * class.
+ */
+ class WarnUnimplemented : public SparcStaticInst
+ {
+ private:
+ /// Have we warned on this instruction yet?
+ mutable bool warned;
+
+ public:
+ /// Constructor
+ WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
+ : SparcStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string
+ FailUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (unimplemented)", mnemonic);
+ }
+
+ std::string
+ WarnUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+#ifdef SS_COMPATIBLE_DISASSEMBLY
+ return csprintf("%-10s", mnemonic);
+#else
+ return csprintf("%-10s (unimplemented)", mnemonic);
+#endif
+ }
+}};
+
+output exec {{
+ Fault
+ FailUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("attempt to execute unimplemented instruction '%s' "
+ "(inst 0x%08x)", mnemonic, machInst);
+ return NoFault;
+ }
+
+ Fault
+ WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ if (!warned) {
+ warn("instruction '%s' unimplemented\n", mnemonic);
+ warned = true;
+ }
+
+ return NoFault;
+ }
+}};
+
+
+def format FailUnimpl() {{
+ iop = InstObjParams(name, 'FailUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
+def format WarnUnimpl() {{
+ iop = InstObjParams(name, 'WarnUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+