Fix up microcode support.
src/arch/sparc/isa/formats/blockmem.isa: Several small and medium bug fixes. src/cpu/simple/base.cc: Fixed a few compiler errors and made sure the next micro pc is set to 1 to prevent the first microop from executing twice. Also fixed a fetching bug. src/cpu/thread_state.cc: Made sure the microPC and nextMicroPC are initialized properly. --HG-- extra : convert_revision : a0fc8aa18d1ade916f17c557181a793c6108a8af
This commit is contained in:
parent
7fefa2a621
commit
f1661baf30
|
@ -16,9 +16,6 @@ output header {{
|
||||||
ExtMachInst _machInst, OpClass __opClass) :
|
ExtMachInst _machInst, OpClass __opClass) :
|
||||||
SparcMacroInst(mnem, _machInst, __opClass, 8)
|
SparcMacroInst(mnem, _machInst, __opClass, 8)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string generateDisassembly(Addr pc,
|
|
||||||
const SymbolTable *symtab) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockMemImm : public BlockMem
|
class BlockMemImm : public BlockMem
|
||||||
|
@ -32,9 +29,6 @@ output header {{
|
||||||
imm(sext<13>(SIMM13))
|
imm(sext<13>(SIMM13))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string generateDisassembly(Addr pc,
|
|
||||||
const SymbolTable *symtab) const;
|
|
||||||
|
|
||||||
const int32_t imm;
|
const int32_t imm;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,7 +68,7 @@ output header {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
output decoder {{
|
output decoder {{
|
||||||
std::string BlockMem::generateDisassembly(Addr pc,
|
std::string BlockMemMicro::generateDisassembly(Addr pc,
|
||||||
const SymbolTable *symtab) const
|
const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
@ -101,7 +95,7 @@ output decoder {{
|
||||||
return response.str();
|
return response.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BlockMemImm::generateDisassembly(Addr pc,
|
std::string BlockMemImmMicro::generateDisassembly(Addr pc,
|
||||||
const SymbolTable *symtab) const
|
const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
@ -165,17 +159,14 @@ def template BlockMemDeclare {{
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
//Constructor
|
||||||
%(class_name)s(MachInst machInst);
|
%(class_name)s(ExtMachInst machInst);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class %(class_name)s_0 : public %(base_class)sMicro
|
class %(class_name)s_0 : public %(base_class)sMicro
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
//Constructor
|
||||||
%(class_name)s_0(MachInst machInst) :
|
%(class_name)s_0(ExtMachInst machInst);
|
||||||
%(base_class)sMicro("%(mnemonic)s[0]",
|
|
||||||
machInst, %(op_class)s, 0*8)
|
|
||||||
{;}
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -183,10 +174,7 @@ def template BlockMemDeclare {{
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
//Constructor
|
||||||
%(class_name)s_1(MachInst machInst) :
|
%(class_name)s_1(ExtMachInst machInst);
|
||||||
%(base_class)sMicro("%(mnemonic)s[1]",
|
|
||||||
machInst, %(op_class)s, 1*8)
|
|
||||||
{;}
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,10 +182,7 @@ def template BlockMemDeclare {{
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
//Constructor
|
||||||
%(class_name)s_2(MachInst machInst) :
|
%(class_name)s_2(ExtMachInst machInst);
|
||||||
%(base_class)sMicro("%(mnemonic)s[2]",
|
|
||||||
machInst, %(op_class)s, 2*8)
|
|
||||||
{;}
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -205,10 +190,7 @@ def template BlockMemDeclare {{
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
//Constructor
|
||||||
%(class_name)s_3(MachInst machInst) :
|
%(class_name)s_3(ExtMachInst machInst);
|
||||||
%(base_class)sMicro("%(mnemonic)s[3]",
|
|
||||||
machInst, %(op_class)s, 3*8)
|
|
||||||
{;}
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -216,10 +198,7 @@ def template BlockMemDeclare {{
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
//Constructor
|
||||||
%(class_name)s_4(MachInst machInst) :
|
%(class_name)s_4(ExtMachInst machInst);
|
||||||
%(base_class)sMicro("%(mnemonic)s[4]",
|
|
||||||
machInst, %(op_class)s, 4*8)
|
|
||||||
{;}
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -227,10 +206,7 @@ def template BlockMemDeclare {{
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
//Constructor
|
||||||
%(class_name)s_5(MachInst machInst) :
|
%(class_name)s_5(ExtMachInst machInst);
|
||||||
%(base_class)sMicro("%(mnemonic)s[5]",
|
|
||||||
machInst, %(op_class)s, 5*8)
|
|
||||||
{;}
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -238,10 +214,7 @@ def template BlockMemDeclare {{
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
//Constructor
|
||||||
%(class_name)s_6(MachInst machInst) :
|
%(class_name)s_6(ExtMachInst machInst);
|
||||||
%(base_class)sMicro("%(mnemonic)s[6]",
|
|
||||||
machInst, %(op_class)s, 6*8)
|
|
||||||
{;}
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -249,12 +222,7 @@ def template BlockMemDeclare {{
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
//Constructor
|
||||||
%(class_name)s_7(MachInst machInst) :
|
%(class_name)s_7(ExtMachInst machInst);
|
||||||
%(base_class)sMicro("%(mnemonic)s[7]",
|
|
||||||
machInst, %(op_class)s, 7*8)
|
|
||||||
{
|
|
||||||
flags[IsLastMicroOp] = true;
|
|
||||||
}
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -262,7 +230,7 @@ def template BlockMemDeclare {{
|
||||||
|
|
||||||
// Basic instruction class constructor template.
|
// Basic instruction class constructor template.
|
||||||
def template BlockMemConstructor {{
|
def template BlockMemConstructor {{
|
||||||
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)
|
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
|
||||||
{
|
{
|
||||||
%(constructor)s;
|
%(constructor)s;
|
||||||
|
@ -277,16 +245,28 @@ def template BlockMemConstructor {{
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
def template MicroLoadExecute {{
|
def template MicroLoadExecute {{
|
||||||
Fault %(class_name)s_%(micro_pc)s::execute(%(CPU_exec_context)s *xc,
|
Fault %(class_name)s::%(class_name)s_%(micro_pc)s::execute(
|
||||||
Trace::InstRecord *traceData) const
|
%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
Addr EA;
|
Addr EA;
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
%(fault_check)s;
|
|
||||||
%(ea_code)s;
|
%(ea_code)s;
|
||||||
|
%(fault_check)s;
|
||||||
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
||||||
xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
|
xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
|
||||||
%(code)s;
|
%(code)s;
|
||||||
|
@ -310,8 +290,8 @@ def template MicroStoreExecute {{
|
||||||
Addr EA;
|
Addr EA;
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
%(fault_check)s;
|
|
||||||
%(ea_code)s;
|
%(ea_code)s;
|
||||||
|
%(fault_check)s;
|
||||||
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
||||||
%(code)s;
|
%(code)s;
|
||||||
|
|
||||||
|
@ -334,14 +314,17 @@ let {{
|
||||||
# those that are only available in hpriv
|
# those that are only available in hpriv
|
||||||
faultCheck = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
|
faultCheck = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
|
||||||
return new PrivilegedAction;
|
return new PrivilegedAction;
|
||||||
if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2))
|
if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2))
|
||||||
return new PrivilegedAction;
|
return new PrivilegedAction;
|
||||||
if(RD & 0xf)
|
//The LSB can be zero, since it's really the MSB in doubles
|
||||||
|
//and quads
|
||||||
|
if(RD & 0xe)
|
||||||
return new IllegalInstruction;
|
return new IllegalInstruction;
|
||||||
if(EA & 0x3f)
|
if(EA & 0x3f)
|
||||||
return new MemAddressNotAligned;'''
|
return new MemAddressNotAligned;
|
||||||
addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
|
'''
|
||||||
addrCalcImm = 'EA = Rs1 + imm + offset;'
|
addrCalcReg = 'EA = Rs1 + Rs2 + offset * 8;'
|
||||||
|
addrCalcImm = 'EA = Rs1 + imm + offset * 8;'
|
||||||
iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
|
iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
|
||||||
iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
|
iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
|
||||||
header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
|
header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
|
||||||
|
@ -350,15 +333,22 @@ let {{
|
||||||
matcher = re.compile(r'Frd_N')
|
matcher = re.compile(r'Frd_N')
|
||||||
exec_output = ''
|
exec_output = ''
|
||||||
for microPC in range(8):
|
for microPC in range(8):
|
||||||
|
flag_code = ''
|
||||||
|
if (microPC == 7):
|
||||||
|
flag_code = "flags[IsLastMicroOp] = true"
|
||||||
pcedCode = matcher.sub("Frd_%d" % microPC, code)
|
pcedCode = matcher.sub("Frd_%d" % microPC, code)
|
||||||
iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
|
iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
|
||||||
opt_flags, {"ea_code": addrCalcReg,
|
opt_flags, {"ea_code": addrCalcReg,
|
||||||
"fault_check": faultCheck, "micro_pc": microPC})
|
"fault_check": faultCheck, "micro_pc": microPC,
|
||||||
|
"set_flags": flag_code})
|
||||||
iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode,
|
iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode,
|
||||||
opt_flags, {"ea_code": addrCalcImm,
|
opt_flags, {"ea_code": addrCalcImm,
|
||||||
"fault_check": faultCheck, "micro_pc": microPC})
|
"fault_check": faultCheck, "micro_pc": microPC,
|
||||||
|
"set_flags": flag_code})
|
||||||
exec_output += execute.subst(iop)
|
exec_output += execute.subst(iop)
|
||||||
exec_output += execute.subst(iop_imm)
|
exec_output += execute.subst(iop_imm)
|
||||||
|
decoder_output += BlockMemMicroConstructor.subst(iop)
|
||||||
|
decoder_output += BlockMemMicroConstructor.subst(iop_imm)
|
||||||
faultCheck = ''
|
faultCheck = ''
|
||||||
return (header_output, decoder_output, exec_output, decode_block)
|
return (header_output, decoder_output, exec_output, decode_block)
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -402,10 +402,12 @@ BaseSimpleCPU::preExecute()
|
||||||
if (instPtr->isMacroOp()) {
|
if (instPtr->isMacroOp()) {
|
||||||
curMacroStaticInst = instPtr;
|
curMacroStaticInst = instPtr;
|
||||||
curStaticInst = curMacroStaticInst->fetchMicroOp(0);
|
curStaticInst = curMacroStaticInst->fetchMicroOp(0);
|
||||||
|
} else {
|
||||||
|
curStaticInst = instPtr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Read the next micro op from the macro op
|
//Read the next micro op from the macro op
|
||||||
curStaticInst = curMacroStaticInst->fetchMicroOp(thread->readMicroPc());
|
curStaticInst = curMacroStaticInst->fetchMicroOp(thread->readMicroPC());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -464,17 +466,17 @@ BaseSimpleCPU::advancePC(Fault fault)
|
||||||
assert(curMacroStaticInst);
|
assert(curMacroStaticInst);
|
||||||
//Close out this macro op, and clean up the
|
//Close out this macro op, and clean up the
|
||||||
//microcode state
|
//microcode state
|
||||||
curMacroStaticInst = nullStaticInst;
|
curMacroStaticInst = StaticInst::nullStaticInstPtr;
|
||||||
thread->setMicroPC(0);
|
thread->setMicroPC(0);
|
||||||
thread->setNextMicroPC(0);
|
thread->setNextMicroPC(1);
|
||||||
}
|
}
|
||||||
//If we're still in a macro op
|
//If we're still in a macro op
|
||||||
if (curMacroStaticInst) {
|
if (curMacroStaticInst) {
|
||||||
//Advance the micro pc
|
//Advance the micro pc
|
||||||
thread->setMicroPC(thread->getNextMicroPC());
|
thread->setMicroPC(thread->readNextMicroPC());
|
||||||
//Advance the "next" micro pc. Note that there are no delay
|
//Advance the "next" micro pc. Note that there are no delay
|
||||||
//slots, and micro ops are "word" addressed.
|
//slots, and micro ops are "word" addressed.
|
||||||
thread->setNextMicroPC(thread->getNextMicroPC() + 1);
|
thread->setNextMicroPC(thread->readNextMicroPC() + 1);
|
||||||
} else {
|
} else {
|
||||||
// go to the next instruction
|
// go to the next instruction
|
||||||
thread->setPC(thread->readNextPC());
|
thread->setPC(thread->readNextPC());
|
||||||
|
|
|
@ -42,13 +42,13 @@
|
||||||
ThreadState::ThreadState(int _cpuId, int _tid)
|
ThreadState::ThreadState(int _cpuId, int _tid)
|
||||||
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
|
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
|
||||||
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
|
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
|
||||||
funcExeInst(0), storeCondFailures(0)
|
microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0)
|
||||||
#else
|
#else
|
||||||
ThreadState::ThreadState(int _cpuId, int _tid, Process *_process,
|
ThreadState::ThreadState(int _cpuId, int _tid, Process *_process,
|
||||||
short _asid, MemObject *mem)
|
short _asid, MemObject *mem)
|
||||||
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
|
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
|
||||||
process(_process), asid(_asid),
|
process(_process), asid(_asid),
|
||||||
funcExeInst(0), storeCondFailures(0)
|
microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
numInst = 0;
|
numInst = 0;
|
||||||
|
|
Loading…
Reference in a new issue