let {{
global rcs_id
- rcs_id = "$Id: s.isa_desc 1.43 04/02/29 22:41:10-05:00 ehallnor@zazzer.eecs.umich.edu $"
+ rcs_id = "$Id$"
}};
#include "base/misc.hh"
#include "cpu/exec_context.hh"
#include "cpu/exetrace.hh"
-#include "cpu/full_cpu/full_cpu.hh"
-#include "cpu/full_cpu/op_class.hh"
-#include "cpu/full_cpu/spec_state.hh"
+#include "cpu/full_cpu/dyn_inst.hh"
#include "cpu/simple_cpu/simple_cpu.hh"
#include "cpu/static_inst.hh"
#include "sim/annotation.hh"
/// @retval Full-system mode: No_Fault if FP is enabled, Fen_Fault
/// if not. Non-full-system mode: always returns No_Fault.
#ifdef FULL_SYSTEM
- inline Fault checkFpEnableFault(ExecContext *xc)
+ template <class XC>
+ inline Fault checkFpEnableFault(XC *xc)
{
Fault fault = No_Fault; // dummy... this ipr access should not fault
if (!ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) {
return fault;
}
#else
- inline Fault checkFpEnableFault(ExecContext *xc)
+ template <class XC>
+ inline Fault checkFpEnableFault(XC *xc)
{
return No_Fault;
}
%(constructor)s;
}
- Fault execute(SimpleCPU *cpu, ExecContext *xc,
- Trace::InstRecord *traceData)
- {
- SimpleCPU *memAccessObj __attribute__((unused)) = cpu;
- Fault fault = No_Fault;
+ %(exec_func_declarations)s
+ };
+}};
- %(fp_enable_check)s;
- %(exec_decl)s;
- %(simple_rd)s;
- %(code)s;
+def template BasicExecute {{
+ Fault %(class_name)s::execute(%(cpu_model)s *xc,
+ Trace::InstRecord *traceData)
+ {
+ Fault fault = No_Fault;
- if (fault == No_Fault) {
- %(simple_wb)s;
- }
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
- return fault;
+ if (fault == No_Fault) {
+ %(op_wb)s;
}
- Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
- Trace::InstRecord *traceData)
- {
- DynInst *memAccessObj __attribute__((unused)) = dynInst;
- Fault fault = No_Fault;
-
- %(fp_enable_check)s;
- %(exec_decl)s;
- %(dtld_rd)s;
- %(code)s;
-
- if (fault == No_Fault) {
- %(dtld_wb)s;
- }
-
- return fault;
- }
- };
+ return fault;
+ }
}};
def template BasicDecode {{
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), flags)
- return iop.subst('BasicDeclare', 'BasicDecode')
+ return iop.subst('BasicDeclare', 'BasicDecode', 'BasicExecute')
}};
~Nop() { }
- Fault execute(SimpleCPU *cpu, ExecContext *xc,
- Trace::InstRecord *traceData)
- {
- return No_Fault;
- }
-
- Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
- Trace::InstRecord *traceData)
- {
- return No_Fault;
- }
-
std::string generateDisassembly(Addr pc, const SymbolTable *symtab)
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return csprintf("%-10s (%s)", "nop", originalDisassembly);
#endif
}
+
+ Fault execute(SimpleCPUExecContext *, Trace::InstRecord *)
+ { return No_Fault; }
+
+ Fault execute(FullCPUExecContext *, Trace::InstRecord *)
+ { return No_Fault; }
};
/// Helper function for decoding nops. Substitute Nop object
}};
def format Nop() {{
- return ('', 'return new Nop("%s", machInst);\n' % name)
+ return ('', 'return new Nop("%s", machInst);\n' % name, 'return No_Fault;')
}};
def format BasicOperateWithNopCheck(code, *opt_args) {{
iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code),
opt_args)
- return iop.subst('BasicDeclare', 'OperateNopCheckDecode')
+ return iop.subst('BasicDeclare', 'OperateNopCheckDecode', 'BasicExecute')
}};
# generate declaration for register version
cblk = CodeBlock(code)
iop = InstObjParams(name, Name, 'AlphaStaticInst', cblk, opt_flags)
- decls = iop.subst('BasicDeclare')
+ (decls, exec_code) = iop.subst('BasicDeclare', 'BasicExecute')
if uses_imm:
# append declaration for imm version
imm_cblk = CodeBlock(imm_code)
imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_cblk,
opt_flags)
- decls += imm_iop.subst('BasicDeclare')
+ (imm_decls, imm_exec_code) = \
+ imm_iop.subst('BasicDeclare', 'BasicExecute')
+ decls += imm_decls
+ exec_code += imm_exec_code
# decode checks IMM bit to pick correct version
decode = iop.subst('RegOrImmDecode')
else:
# no imm version: just check for nop
decode = iop.subst('OperateNopCheckDecode')
- return (decls, decode)
+ return (decls, decode, exec_code)
}};
#if defined(linux)
int
- getC99RoundingMode(ExecContext *xc)
+ getC99RoundingMode(uint64_t fpcr_val)
{
if (roundingMode == Dynamic) {
- return alphaToC99RoundingMode[bits(xc->readFpcr(), 59, 58)];
+ return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)];
}
else {
return alphaToC99RoundingMode[roundingMode];
}};
-def template FloatingPointDeclare {{
- /**
- * "Fast" static instruction class for "%(mnemonic)s" (imprecise
- * trapping mode, normal rounding mode).
- */
- class %(class_name)sFast : public %(base_class)s
- {
- public:
- /// Constructor.
- %(class_name)sFast(MachInst machInst)
- : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
- {
- %(constructor)s;
- }
-
- Fault execute(SimpleCPU *cpu, ExecContext *xc,
- Trace::InstRecord *traceData)
- {
- Fault fault = No_Fault;
-
- %(fp_enable_check)s;
- %(exec_decl)s;
- %(simple_rd)s;
- %(code)s;
-
- if (fault == No_Fault) {
- %(simple_wb)s;
- }
-
- return fault;
- }
-
- Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
- Trace::InstRecord *traceData)
- {
- Fault fault = No_Fault;
-
- %(fp_enable_check)s;
- %(exec_decl)s;
- %(dtld_rd)s;
- %(code)s;
-
- if (fault == No_Fault) {
- %(dtld_wb)s;
- }
-
- return fault;
- }
- };
-
- /**
- * General static instruction class for "%(mnemonic)s". Supports
- * all the various rounding and trapping modes.
- */
- class %(class_name)sGeneral : public %(base_class)s
- {
- public:
- /// Constructor.
- %(class_name)sGeneral(MachInst machInst)
- : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
- {
- %(constructor)s;
- }
-
- Fault execute(SimpleCPU *cpu, ExecContext *xc,
- Trace::InstRecord *traceData)
- {
- Fault fault = No_Fault;
-
- %(fp_enable_check)s;
- %(exec_decl)s;
- %(simple_rd)s;
-
-#if defined(linux)
- fesetround(getC99RoundingMode(xc));
-#endif
-
- %(code)s;
-
-#if defined(linux)
- fesetround(FE_TONEAREST);
-#endif
-
- if (fault == No_Fault) {
- %(simple_wb)s;
- }
-
- return fault;
- }
-
- Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
- Trace::InstRecord *traceData)
- {
- Fault fault = No_Fault;
-
- %(fp_enable_check)s;
- %(exec_decl)s;
- %(dtld_rd)s;
-
-#if defined(linux)
- fesetround(getC99RoundingMode(xc));
-#endif
-
- %(code)s;
-
-#if defined(linux)
- fesetround(FE_TONEAREST);
-#endif
-
- if (fault == No_Fault) {
- %(dtld_wb)s;
- }
-
- return fault;
- }
- };
-}};
-
def template FloatingPointDecode {{
{
bool fast = (FP_TRAPMODE == AlphaFP::Imprecise
}
}};
-
// General format for floating-point operate instructions:
// - Checks trapping and rounding mode flags. Trapping modes
// currently unimplemented (will fail).
// - Generates NOP if FC == 31.
def format FloatingPointOperate(code, *opt_args) {{
- iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code),
- opt_args)
- return iop.subst('FloatingPointDeclare', 'FloatingPointDecode')
+ iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
+ decode = iop.subst('FloatingPointDecode')
+
+ fast_iop = InstObjParams(name, Name + 'Fast', 'AlphaFP',
+ CodeBlock(code), opt_args)
+ (fast_declare, fast_exec) = fast_iop.subst('BasicDeclare', 'BasicExecute')
+
+ gen_code_prefix = r'''
+#if defined(linux)
+ fesetround(getC99RoundingMode(xc->readFpcr()));
+#endif
+'''
+ gen_code_suffix = r'''
+#if defined(linux)
+ fesetround(FE_TONEAREST);
+#endif
+'''
+
+ gen_iop = InstObjParams(name, Name + 'General', 'AlphaFP',
+ CodeBlock(gen_code_prefix + code + gen_code_suffix), opt_args)
+ (gen_declare, gen_exec) = gen_iop.subst('BasicDeclare', 'BasicExecute')
+
+ return (fast_declare + gen_declare, decode, fast_exec + gen_exec)
}};
{
}
- Fault execute(SimpleCPU *cpu, ExecContext *xc,
- Trace::InstRecord *traceData)
- { panic("attempt to execute eacomp"); }
+ Fault execute(SimpleCPUExecContext *, Trace::InstRecord *)
+ { panic("attempt to execute eacomp"); }
- Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
- Trace::InstRecord *traceData)
- { panic("attempt to execute eacomp"); }
+ Fault execute(FullCPUExecContext *, Trace::InstRecord *)
+ { panic("attempt to execute eacomp"); }
};
/**
{
}
- Fault execute(SimpleCPU *cpu, ExecContext *xc,
- Trace::InstRecord *traceData)
- { panic("attempt to execute memacc"); }
+ Fault execute(SimpleCPUExecContext *, Trace::InstRecord *)
+ { panic("attempt to execute memacc"); }
- Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
- Trace::InstRecord *traceData)
- { panic("attempt to execute memacc"); }
+ Fault execute(FullCPUExecContext *, Trace::InstRecord *)
+ { panic("attempt to execute memacc"); }
};
}};
def format LoadAddress(code) {{
iop = InstObjParams(name, Name, 'Memory', CodeBlock(code))
- return iop.subst('BasicDeclare', 'BasicDecode')
+ return iop.subst('BasicDeclare', 'BasicDecode', 'BasicExecute')
}};
%(constructor)s;
}
- Fault execute(SimpleCPU *cpu, ExecContext *xc,
- Trace::InstRecord *traceData)
- {
- SimpleCPU *memAccessObj = cpu;
- Addr EA;
- Fault fault = No_Fault;
-
- %(fp_enable_check)s;
- %(exec_decl)s;
- %(simple_nonmem_rd)s;
- %(ea_code)s;
-
- if (fault == No_Fault) {
- %(simple_mem_rd)s;
- %(memacc_code)s;
- }
-
- if (fault == No_Fault) {
- %(simple_mem_wb)s;
- }
+ %(exec_func_declarations)s
+ };
+}};
- if (fault == No_Fault) {
- %(postacc_code)s;
- }
+def template LoadStoreExecute {{
+ Fault %(class_name)s::execute(%(cpu_model)s *xc,
+ Trace::InstRecord *traceData)
+ {
+ Addr EA;
+ Fault fault = No_Fault;
- if (fault == No_Fault) {
- %(simple_nonmem_wb)s;
- }
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_nonmem_rd)s;
+ %(ea_code)s;
- return fault;
+ if (fault == No_Fault) {
+ %(op_mem_rd)s;
+ %(memacc_code)s;
}
- Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
- Trace::InstRecord *traceData)
- {
- DynInst *memAccessObj = dynInst;
- Addr EA;
- Fault fault = No_Fault;
-
- %(fp_enable_check)s;
- %(exec_decl)s;
- %(dtld_nonmem_rd)s;
- %(ea_code)s;
-
- if (fault == No_Fault) {
- %(dtld_mem_rd)s;
- %(memacc_code)s;
- }
-
- if (fault == No_Fault) {
- %(dtld_mem_wb)s;
- }
-
- if (fault == No_Fault) {
- %(postacc_code)s;
- }
+ if (fault == No_Fault) {
+ %(op_mem_wb)s;
+ }
- if (fault == No_Fault) {
- %(dtld_nonmem_wb)s;
- }
+ if (fault == No_Fault) {
+ %(postacc_code)s;
+ }
- return fault;
+ if (fault == No_Fault) {
+ %(op_nonmem_wb)s;
}
- };
-}};
+ return fault;
+ }
+}};
def template PrefetchDeclare {{
/**
%(constructor)s;
}
- Fault execute(SimpleCPU *cpu, ExecContext *xc,
- Trace::InstRecord *traceData)
- {
- Addr EA;
- Fault fault = No_Fault;
+ %(exec_func_declarations)s
+ };
+}};
- %(fp_enable_check)s;
- %(exec_decl)s;
- %(simple_nonmem_rd)s;
- %(ea_code)s;
+def template PrefetchExecute {{
+ Fault %(class_name)s::execute(%(cpu_model)s *xc,
+ Trace::InstRecord *traceData)
+ {
+ Addr EA;
+ Fault fault = No_Fault;
- if (fault == No_Fault) {
- cpu->prefetch(EA, memAccessFlags);
- }
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_nonmem_rd)s;
+ %(ea_code)s;
- return No_Fault;
+ if (fault == No_Fault) {
+ xc->prefetch(EA, memAccessFlags);
}
- Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
- Trace::InstRecord *traceData)
- {
- Addr EA;
- Fault fault = No_Fault;
-
- %(fp_enable_check)s;
- %(exec_decl)s;
- %(dtld_nonmem_rd)s;
- %(ea_code)s;
-
- if (fault == No_Fault) {
- dynInst->prefetch(EA, memAccessFlags);
- }
-
- return No_Fault;
- }
- };
+ return No_Fault;
+ }
}};
-
// load instructions use Ra as dest, so check for
// Ra == 31 to detect nops
def template LoadNopCheckDecode {{
def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '',
base_class = 'Memory', flags = [],
declare_template = 'LoadStoreDeclare',
- decode_template = 'BasicDecode'):
+ decode_template = 'BasicDecode',
+ exec_template = 'LoadStoreExecute'):
# Segregate flags into instruction flags (handled by InstObjParams)
# and memory access flags (handled here).
if mem_flags != '':
iop.constructor += '\n\tmemAccessFlags = ' + mem_flags + ';'
- return iop.subst(declare_template, decode_template)
+ return iop.subst(declare_template, decode_template, exec_template)
}};
// Note that the flags passed in apply only to the prefetch version
def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{
# declare the load instruction object and generate the decode block
- (decls, decode) = \
+ (decls, decode, exec_code) = \
LoadStoreBase(name, Name, ea_code, memacc_code,
decode_template = 'LoadPrefetchCheckDecode')
# convert flags from tuple to list to make them mutable
pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'RdPort']
- (pfdecls, pfdecode) = \
+ (pfdecls, pfdecode, pfexec) = \
LoadStoreBase(name, Name + 'Prefetch', ea_code, '',
flags = pf_flags,
- declare_template = 'PrefetchDeclare')
+ declare_template = 'PrefetchDeclare',
+ exec_template = 'PrefetchExecute')
- return (decls + pfdecls, decode)
+ return (decls + pfdecls, decode, exec_code + pfexec)
}};
code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n';
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
('IsDirectControl', 'IsCondControl'))
- return iop.subst('BasicDeclare', 'BasicDecode')
+ return iop.subst('BasicDeclare', 'BasicDecode', 'BasicExecute')
}};
let {{
nolink_code = 'NPC = %s;\n' % npc_expr
nolink_iop = InstObjParams(name, Name, base_class,
CodeBlock(nolink_code), flags)
- decls = nolink_iop.subst('BasicDeclare')
+ (decls, exec_code) = nolink_iop.subst('BasicDeclare', 'BasicExecute')
# Generate declaration of '*AndLink' version, append to decls
link_code = 'Ra = NPC & ~3;\n' + nolink_code
link_iop = InstObjParams(name, Name + 'AndLink', base_class,
CodeBlock(link_code), flags)
- decls += link_iop.subst('BasicDeclare')
+ (link_decls, link_exec_code) = \
+ link_iop.subst('BasicDeclare', 'BasicExecute')
+ decls += link_decls
+ exec_code += link_exec_code
# need to use link_iop for the decode template since it is expecting
# the shorter version of class_name (w/o "AndLink")
- return (decls, nolink_iop.subst('JumpOrBranchDecode'))
+ return (decls, nolink_iop.subst('JumpOrBranchDecode'), exec_code)
}};
def format UncondBranch(*flags) {{
def format EmulatedCallPal(code) {{
iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code))
- return iop.subst('BasicDeclare', 'BasicDecode')
+ return iop.subst('BasicDeclare', 'BasicDecode', 'BasicExecute')
}};
declare {{
def format CallPal(code) {{
iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code))
- return iop.subst('BasicDeclare', 'BasicDecode')
+ return iop.subst('BasicDeclare', 'BasicDecode', 'BasicExecute')
}};
//
def format HwMoveIPR(code) {{
iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code))
- return iop.subst('BasicDeclare', 'BasicDecode')
+ return iop.subst('BasicDeclare', 'BasicDecode', 'BasicExecute')
}};
declare {{
{
}
- Fault execute(SimpleCPU *cpu, ExecContext *xc,
+ Fault execute(SimpleCPUExecContext *xc,
Trace::InstRecord *traceData)
{
panic("attempt to execute unimplemented instruction '%s' "
return Unimplemented_Opcode_Fault;
}
- Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
+ Fault execute(FullCPUExecContext *xc,
Trace::InstRecord *traceData)
{
// don't panic if this is a misspeculated instruction
- if (!xc->spec_mode)
+ if (!xc->misspeculating())
panic("attempt to execute unimplemented instruction '%s' "
"(inst 0x%08x, opcode 0x%x)",
mnemonic, machInst, OPCODE);
{
}
- Fault execute(SimpleCPU *cpu, ExecContext *xc,
+ Fault execute(SimpleCPUExecContext *xc,
Trace::InstRecord *traceData)
{
if (!warned) {
return No_Fault;
}
- Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
+ Fault execute(FullCPUExecContext *xc,
Trace::InstRecord *traceData)
{
- if (!xc->spec_mode && !warned) {
+ if (!xc->misspeculating() && !warned) {
warn("instruction '%s' unimplemented\n", mnemonic);
warned = true;
}
def format FailUnimpl() {{
iop = InstObjParams(name, 'FailUnimplemented')
- return ('', iop.subst('BasicDecodeWithMnemonic'))
+ return ('', iop.subst('BasicDecodeWithMnemonic'), '')
}};
def format WarnUnimpl() {{
iop = InstObjParams(name, Name, 'WarnUnimplemented')
- return iop.subst('WarnUnimplDeclare', 'BasicDecode')
+ return iop.subst('WarnUnimplDeclare', 'BasicDecode') + ['']
}};
declare {{
{
}
- Fault execute(SimpleCPU *cpu, ExecContext *xc,
+ Fault execute(SimpleCPUExecContext *xc,
Trace::InstRecord *traceData)
{
panic("attempt to execute unknown instruction "
return Unimplemented_Opcode_Fault;
}
- Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
+ Fault execute(FullCPUExecContext *xc,
Trace::InstRecord *traceData)
{
// don't panic if this is a misspeculated instruction
- if (!xc->spec_mode)
+ if (!xc->misspeculating())
panic("attempt to execute unknown instruction "
"(inst 0x%08x, opcode 0x%x)", machInst, OPCODE);
return Unimplemented_Opcode_Fault;
}};
def format Unknown() {{
- return ('', 'return new Unknown(machInst);\n')
+ return ('', 'return new Unknown(machInst);\n', '')
}};
declare {{
0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED);
0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED);
0x20: copy_load({{EA = Ra;}},
- {{ fault = memAccessObj->copySrcTranslate(EA);}},
+ {{ fault = xc->copySrcTranslate(EA);}},
IsMemRef, IsLoad, IsCopy);
}
0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }});
0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }});
0x24: copy_store({{EA = Rb;}},
- {{ fault = memAccessObj->copy(EA);}},
+ {{ fault = xc->copy(EA);}},
IsMemRef, IsStore, IsCopy);
}
format MiscPrefetch {
0xf800: wh64({{ EA = Rb; }},
- {{ memAccessObj->writeHint(EA, 64); }},
+ {{ xc->writeHint(EA, 64); }},
IsMemRef, IsStore, WrPort);
}
#ifdef FULL_SYSTEM
format BasicOperate {
0xe000: rc({{
- Ra = xc->regs.intrflag;
+ Ra = xc->readIntrFlag();
if (!xc->misspeculating()) {
- xc->regs.intrflag = 0;
+ xc->setIntrFlag(0);
}
}});
0xf000: rs({{
- Ra = xc->regs.intrflag;
+ Ra = xc->readIntrFlag();
if (!xc->misspeculating()) {
- xc->regs.intrflag = 1;
+ xc->setIntrFlag(1);
}
}});
}
// on this PAL call (including maybe suppress it)
dopal = xc->simPalCheck(palFunc);
- Annotate::Callpal(xc, palFunc);
+ Annotate::Callpal(xc->xcBase(), palFunc);
if (dopal) {
- AlphaISA::swap_palshadow(&xc->regs, true);
+ AlphaISA::swap_palshadow(&xc->xcBase()->regs, true);
xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC);
}
}
0x01: decode M5FUNC {
0x00: arm({{
if (!xc->misspeculating()) {
- Annotate::ARM(xc);
- xc->kernelStats.arm();
+ Annotate::ARM(xc->xcBase());
+ xc->xcBase()->kernelStats.arm();
}
}});
0x01: quiesce({{
if (!xc->misspeculating())
- AlphaPseudo::quiesce(xc);
+ AlphaPseudo::quiesce(xc->xcBase());
}});
0x10: ivlb({{
if (!xc->misspeculating()) {
- Annotate::BeginInterval(xc);
- xc->kernelStats.ivlb();
+ Annotate::BeginInterval(xc->xcBase());
+ xc->xcBase()->kernelStats.ivlb();
}
}}, No_OpClass);
0x11: ivle({{
if (!xc->misspeculating())
- Annotate::EndInterval(xc);
+ Annotate::EndInterval(xc->xcBase());
}}, No_OpClass);
0x20: m5exit_old({{
if (!xc->misspeculating())
- AlphaPseudo::m5exit_old(xc);
+ AlphaPseudo::m5exit_old(xc->xcBase());
}}, No_OpClass);
0x21: m5exit({{
if (!xc->misspeculating())
- AlphaPseudo::m5exit(xc);
+ AlphaPseudo::m5exit(xc->xcBase());
}}, No_OpClass);
- 0x30: initparam({{ Ra = cpu->system->init_param; }});
+ 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }});
0x40: resetstats({{
if (!xc->misspeculating())
- AlphaPseudo::resetstats(xc);
+ AlphaPseudo::resetstats(xc->xcBase());
}});
0x41: dumpstats({{
if (!xc->misspeculating())
- AlphaPseudo::dumpstats(xc);
+ AlphaPseudo::dumpstats(xc->xcBase());
}});
0x42: dumpresetstats({{
if (!xc->misspeculating())
- AlphaPseudo::dumpresetstats(xc);
+ AlphaPseudo::dumpresetstats(xc->xcBase());
}});
0x43: m5checkpoint({{
if (!xc->misspeculating())
- AlphaPseudo::m5checkpoint(xc);
+ AlphaPseudo::m5checkpoint(xc->xcBase());
}});
}
}
format HwMoveIPR {
0x19: hw_mfpr({{
// this instruction is only valid in PAL mode
- if (!PC_PAL(xc->regs.pc)) {
+ if (!xc->inPalMode()) {
fault = Unimplemented_Opcode_Fault;
}
else {
}});
0x1d: hw_mtpr({{
// this instruction is only valid in PAL mode
- if (!PC_PAL(xc->regs.pc)) {
+ if (!xc->inPalMode()) {
fault = Unimplemented_Opcode_Fault;
}
else {
import sys
import re
import string
+import traceback
# get type names
from types import *
-# Check arguments. Right now there are only two: the name of the ISA
-# description (input) file and the name of the C++ decoder (output) file.
-isa_desc_filename = sys.argv[1]
-decoder_filename = sys.argv[2]
-
-# Might as well suck the file in while we're here. This way if it's a
-# bad filename we don't waste a lot of time building the parser :-).
-input = open(isa_desc_filename)
-isa_desc = input.read()
-input.close()
-
# Prepend the directory where the PLY lex & yacc modules are found
# to the search path. Assumes we're compiling in a subdirectory
# of 'build' in the current tree.
isa_name = t[2]
namespace = isa_name + "Inst"
global_decls2 = t[3]
- (inst_decls, code) = t[4]
- code = indent(code)
+ (inst_decls, decode_code, exec_code) = t[4]
+ decode_code = indent(decode_code)
# grab the last three path components of isa_desc_filename
filename = '/'.join(isa_desc_filename.split('/')[-3:])
# if the isa_desc file defines a 'rcs_id' string,
%(inst_decls)s
+%(exec_code)s
+
} // namespace %(namespace)s
//////////////////////
%(isa_name)s::decodeInst(%(isa_name)s::MachInst machInst)
{
using namespace %(namespace)s;
-%(code)s
+%(decode_code)s
} // decodeInst
''' % vars()
output.close()
def p_decode_block(t):
'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE'
default_defaults = defaultStack.pop()
- (decls, code, has_default) = t[5]
+ (decls, decode_code, exec_code, has_default) = t[5]
# use the "default defaults" only if there was no explicit
# default statement in decode_stmt_list
if not has_default:
- (default_decls, default_code) = default_defaults
+ (default_decls, default_decode, default_exec) = default_defaults
decls += default_decls
- code += default_code
+ decode_code += default_decode
+ exec_code += default_exec
t[0] = (decls, '''
switch (%s) {
%s
}
-''' % (t[2], indent(code)))
+''' % (t[2], indent(decode_code)), exec_code)
# The opt_default statement serves only to push the "default defaults"
# onto defaultStack. This value will be used by nested decode blocks,
def p_opt_default_1(t):
'opt_default : DEFAULT inst'
# push the new default
- (decls, code) = t[2]
- defaultStack.push((decls, '\ndefault:\n%sbreak;' % code))
+ (decls, decode_code, exec_code) = t[2]
+ defaultStack.push((decls, '\ndefault:\n%sbreak;' % decode_code, exec_code))
# no meaningful value returned
t[0] = None
def p_decode_stmt_list_1(t):
'decode_stmt_list : decode_stmt decode_stmt_list'
- (decls1, code1, has_default1) = t[1]
- (decls2, code2, has_default2) = t[2]
+ (decls1, decode_code1, exec_code1, has_default1) = t[1]
+ (decls2, decode_code2, exec_code2, has_default2) = t[2]
if (has_default1 and has_default2):
error(t.lineno(1), 'Two default cases in decode block')
- t[0] = (decls1 + '\n' + decls2, code1 + '\n' + code2,
- has_default1 or has_default2)
+ t[0] = (decls1 + '\n' + decls2, decode_code1 + '\n' + decode_code2,
+ exec_code1 + '\n' + exec_code2, has_default1 or has_default2)
#
# Decode statement rules
# the other statements.
def p_decode_stmt_cpp(t):
'decode_stmt : CPPDIRECTIVE'
- t[0] = (t[1], t[1], 0)
+ t[0] = (t[1], t[1], t[1], 0)
# A format block 'format <foo> { ... }' sets the default instruction
# format used to handle instruction definitions inside the block.
def p_decode_stmt_decode(t):
'decode_stmt : case_label COLON decode_block'
(label, is_default) = t[1]
- (decls, code) = t[3]
+ (decls, decode_code, exec_code) = t[3]
# just wrap the decoding code from the block as a case in the
# outer switch statement.
- t[0] = (decls, '\n%s:\n%s' % (label, indent(code)), is_default)
+ t[0] = (decls, '\n%s:\n%s' % (label, indent(decode_code)),
+ exec_code, is_default)
# Instruction definition (finally!).
def p_decode_stmt_inst(t):
'decode_stmt : case_label COLON inst SEMI'
(label, is_default) = t[1]
- (decls, code) = t[3]
- t[0] = (decls, '\n%s:%sbreak;' % (label, indent(code)), is_default)
+ (decls, decode_code, exec_code) = t[3]
+ t[0] = (decls, '\n%s:%sbreak;' % (label, indent(decode_code)),
+ exec_code, is_default)
# The case label is either a list of one or more constants or 'default'
def p_case_label_0(t):
'inst : ID LPAREN arg_list RPAREN'
# Pass the ID and arg list to the current format class to deal with.
currentFormat = formatStack.top()
- (decls, code) = currentFormat.defineInst(t[1], t[3], t.lineno(1))
+ (decls, decode_code, exec_code) = \
+ currentFormat.defineInst(t[1], t[3], t.lineno(1))
args = ','.join(map(str, t[3]))
args = re.sub('(?m)^', '//', args)
args = re.sub('^//', '', args)
comment = '// %s::%s(%s)\n' % (currentFormat.id, t[1], args)
- t[0] = (comment + decls, comment + code)
+ t[0] = (comment + decls, comment + decode_code, comment + exec_code)
# Define an instruction using an explicitly specified format:
# "<fmt>::<mnemonic>(<args>)"
format = formatMap[t[1]]
except KeyError:
error(t.lineno(1), 'instruction format "%s" not defined.' % t[1])
- (decls, code) = format.defineInst(t[3], t[5], t.lineno(1))
+ (decls, decode_code, exec_code) = \
+ format.defineInst(t[3], t[5], t.lineno(1))
comment = '// %s::%s(%s)\n' % (t[1], t[3], t[5])
- t[0] = (comment + decls, comment + code)
+ t[0] = (comment + decls, comment + decode_code, comment + exec_code)
def p_arg_list_0(t):
'arg_list : empty'
code = ' pass\n'
param_list = string.join(params, ", ")
f = 'def defInst(name, Name, ' + param_list + '):\n' + code
- exec(f)
+ c = compile(f, 'def format ' + id, 'exec')
+ exec(c)
self.func = defInst
def defineInst(self, name, args, lineno):
# Like error(), but include a Python stack backtrace (for processing
# Python exceptions).
def error_bt(lineno, string):
+ traceback.print_exc()
print >> sys.stderr, "%s:%d: %s" % (isa_desc_filename, lineno, string)
- raise
+ sys.exit(1)
#####################################################################
(op_desc.dest_reg_idx, self.reg_spec)
return c
- def makeRead(self, op_desc, cpu_model):
+ def makeRead(self, op_desc):
(size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
if (type == 'float' or type == 'double'):
error(0, 'Attempt to read integer register as FP')
return '%s = bits(xc->readIntReg(_srcRegIdx[%d]), %d, 0);\n' % \
(op_desc.munged_name, op_desc.src_reg_idx, size-1)
- def makeWrite(self, op_desc, cpu_model):
+ def makeWrite(self, op_desc):
(size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
if (type == 'float' or type == 'double'):
error(0, 'Attempt to write integer register as FP')
(op_desc.dest_reg_idx, self.reg_spec)
return c
- def makeRead(self, op_desc, cpu_model):
+ def makeRead(self, op_desc):
(size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
bit_select = 0
if (type == 'float'):
else:
return '%s = %s;\n' % (op_desc.munged_name, base)
- def makeWrite(self, op_desc, cpu_model):
+ def makeWrite(self, op_desc):
(size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
final_val = op_desc.munged_name
if (type == 'float'):
(op_desc.dest_reg_idx, self.reg_spec)
return c
- def makeRead(self, op_desc, cpu_model):
+ def makeRead(self, op_desc):
(size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
bit_select = 0
if (type == 'float' or type == 'double'):
return '%s = bits(%s, %d, 0);\n' % \
(op_desc.munged_name, base, size-1)
- def makeWrite(self, op_desc, cpu_model):
+ def makeWrite(self, op_desc):
(size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
if (type == 'float' or type == 'double'):
error(0, 'Attempt to write control register as FP')
c += 'uint64_t %s_write_result = 0;\n' % op_desc.base_name
return c
- def makeRead(self, op_desc, cpu_model):
+ def makeRead(self, op_desc):
(size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
eff_type = 'uint%d_t' % size
- return 'fault = memAccessObj->read(EA, (%s&)%s, %s_flags);\n' \
+ return 'fault = xc->read(EA, (%s&)%s, %s_flags);\n' \
% (eff_type, op_desc.munged_name, op_desc.base_name)
- def makeWrite(self, op_desc, cpu_model):
+ def makeWrite(self, op_desc):
(size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
eff_type = 'uint%d_t' % size
- return 'fault = memAccessObj->write((%s&)%s, EA, %s_flags,' \
+ return 'fault = xc->write((%s&)%s, EA, %s_flags,' \
' &%s_write_result);\n' \
% (eff_type, op_desc.munged_name, op_desc.base_name,
op_desc.base_name)
def makeConstructor(self, op_desc):
return ''
- def makeRead(self, op_desc, cpu_model):
+ def makeRead(self, op_desc):
return '%s = xc->readPC() + 4;\n' % op_desc.munged_name
- def makeWrite(self, op_desc, cpu_model):
+ def makeWrite(self, op_desc):
return 'xc->setNextPC(%s);\n' % op_desc.munged_name
def finalize(self):
self.flags = self.traits.getFlags(self)
self.constructor = self.traits.makeConstructor(self)
- self.exec_decl = self.traits.makeDecl(self)
+ self.op_decl = self.traits.makeDecl(self)
if self.is_src:
- self.simple_rd = self.traits.makeRead(self, 'simple')
- self.dtld_rd = self.traits.makeRead(self, 'dtld')
+ self.op_rd = self.traits.makeRead(self)
else:
- self.simple_rd = ''
- self.dtld_rd = ''
+ self.op_rd = ''
if self.is_dest:
- self.simple_wb = self.traits.makeWrite(self, 'simple')
- self.dtld_wb = self.traits.makeWrite(self, 'dtld')
+ self.op_wb = self.traits.makeWrite(self)
else:
- self.simple_wb = ''
- self.dtld_wb = ''
+ self.op_wb = ''
class OperandDescriptorList:
def __init__(self):
self.constructor += \
'\n\t_numIntDestRegs = %d;' % self.operands.numIntDestRegs
- self.exec_decl = self.operands.concatAttrStrings('exec_decl')
+ self.op_decl = self.operands.concatAttrStrings('op_decl')
is_mem = lambda op: op.traits.isMem()
not_mem = lambda op: not op.traits.isMem()
- self.simple_rd = self.operands.concatAttrStrings('simple_rd')
- self.simple_wb = self.operands.concatAttrStrings('simple_wb')
- self.simple_mem_rd = \
- self.operands.concatSomeAttrStrings(is_mem, 'simple_rd')
- self.simple_mem_wb = \
- self.operands.concatSomeAttrStrings(is_mem, 'simple_wb')
- self.simple_nonmem_rd = \
- self.operands.concatSomeAttrStrings(not_mem, 'simple_rd')
- self.simple_nonmem_wb = \
- self.operands.concatSomeAttrStrings(not_mem, 'simple_wb')
-
- self.dtld_rd = self.operands.concatAttrStrings('dtld_rd')
- self.dtld_wb = self.operands.concatAttrStrings('dtld_wb')
- self.dtld_mem_rd = \
- self.operands.concatSomeAttrStrings(is_mem, 'dtld_rd')
- self.dtld_mem_wb = \
- self.operands.concatSomeAttrStrings(is_mem, 'dtld_wb')
- self.dtld_nonmem_rd = \
- self.operands.concatSomeAttrStrings(not_mem, 'dtld_rd')
- self.dtld_nonmem_wb = \
- self.operands.concatSomeAttrStrings(not_mem, 'dtld_wb')
+ self.op_rd = self.operands.concatAttrStrings('op_rd')
+ self.op_wb = self.operands.concatAttrStrings('op_wb')
+ self.op_mem_rd = \
+ self.operands.concatSomeAttrStrings(is_mem, 'op_rd')
+ self.op_mem_wb = \
+ self.operands.concatSomeAttrStrings(is_mem, 'op_wb')
+ self.op_nonmem_rd = \
+ self.operands.concatSomeAttrStrings(not_mem, 'op_rd')
+ self.op_nonmem_wb = \
+ self.operands.concatSomeAttrStrings(not_mem, 'op_wb')
self.flags = self.operands.concatAttrLists('flags')
self.mnemonic = mnem
self.class_name = class_name
self.base_class = base_class
+ self.exec_func_declarations = '''
+ Fault execute(SimpleCPUExecContext *, Trace::InstRecord *);
+ Fault execute(FullCPUExecContext *, Trace::InstRecord *);
+'''
if code_block:
for code_attr in code_block.__dict__.keys():
setattr(self, code_attr, getattr(code_block, code_attr))
else:
self.fp_enable_check = ''
+ def _subst(self, template):
+ try:
+ return template % self.__dict__
+ except KeyError, key:
+ raise KeyError, 'InstObjParams.subst: no definition for %s' % key
+
def subst(self, *args):
result = []
for t in args:
- if not templateMap.has_key(t):
+ try: template = templateMap[t]
+ except KeyError:
error(0, 'InstObjParams::subst: undefined template "%s"' % t)
- try:
- result.append(templateMap[t] % self.__dict__)
- except KeyError, key:
- error(0, 'InstObjParams::subst: no definition for "%s"' % key)
+ if template.find('%(cpu_model)') != -1:
+ tmp = ''
+ for cpu_model in ('SimpleCPUExecContext', 'FullCPUExecContext'):
+ self.cpu_model = cpu_model
+ tmp += self._subst(template)
+ result.append(tmp)
+ else:
+ result.append(self._subst(template))
if len(args) == 1:
result = result[0]
return result
#
-# All set... read in and parse the ISA description.
+# Read in and parse the ISA description.
#
-yacc.parse(isa_desc)
+def parse_isa_desc(isa_desc_file, decoder_file):
+ # Arguments are the name of the ISA description (input) file and
+ # the name of the C++ decoder (output) file.
+ global isa_desc_filename, decoder_filename
+ isa_desc_filename = isa_desc_file
+ decoder_filename = decoder_file
+
+ # Suck the ISA description file in.
+ input = open(isa_desc_filename)
+ isa_desc = input.read()
+ input.close()
+
+ # Parse it.
+ yacc.parse(isa_desc)
+
+# Called as script: get args from command line.
+if __name__ == '__main__':
+ parse_isa_desc(sys.argv[1], sys.argv[2])