Merge zizzer:/bk/newmem
into zower.eecs.umich.edu:/eecshome/m5/newmem
src/arch/sparc/isa/formats/mem/blockmem.isa:
src/arch/sparc/isa/operands.isa:
Hand Merge
--HG--
extra : convert_revision : 4c54544e5c7a61f055ea9b00ccf5f8510df0e6c2
This commit is contained in:
@@ -1009,7 +1009,7 @@ decode OP default Unknown::unknown()
|
||||
0x00: lduw({{Rd = Mem.uw;}});
|
||||
0x01: ldub({{Rd = Mem.ub;}});
|
||||
0x02: lduh({{Rd = Mem.uhw;}});
|
||||
0x03: ldd({{
|
||||
0x03: ldtw({{
|
||||
uint64_t val = Mem.udw;
|
||||
RdLow = val<31:0>;
|
||||
RdHigh = val<63:32>;
|
||||
@@ -1019,7 +1019,7 @@ decode OP default Unknown::unknown()
|
||||
0x04: stw({{Mem.uw = Rd.sw;}});
|
||||
0x05: stb({{Mem.ub = Rd.sb;}});
|
||||
0x06: sth({{Mem.uhw = Rd.shw;}});
|
||||
0x07: std({{Mem.udw = RdLow<31:0> | (RdHigh<31:0> << 32);}});
|
||||
0x07: sttw({{Mem.udw = RdLow<31:0> | (RdHigh<31:0> << 32);}});
|
||||
}
|
||||
format Load {
|
||||
0x08: ldsw({{Rd = (int32_t)Mem.sw;}});
|
||||
@@ -1039,7 +1039,7 @@ decode OP default Unknown::unknown()
|
||||
0x10: lduwa({{Rd = Mem.uw;}}, {{EXT_ASI}});
|
||||
0x11: lduba({{Rd = Mem.ub;}}, {{EXT_ASI}});
|
||||
0x12: lduha({{Rd = Mem.uhw;}}, {{EXT_ASI}});
|
||||
0x13: ldda({{
|
||||
0x13: ldtwa({{
|
||||
uint64_t val = Mem.udw;
|
||||
RdLow = val<31:0>;
|
||||
RdHigh = val<63:32>;
|
||||
@@ -1049,7 +1049,7 @@ decode OP default Unknown::unknown()
|
||||
0x14: stwa({{Mem.uw = Rd;}}, {{EXT_ASI}});
|
||||
0x15: stba({{Mem.ub = Rd;}}, {{EXT_ASI}});
|
||||
0x16: stha({{Mem.uhw = Rd;}}, {{EXT_ASI}});
|
||||
0x17: stda({{Mem.udw = RdLow<31:0> | RdHigh<31:0> << 32;}}, {{EXT_ASI}});
|
||||
0x17: sttwa({{Mem.udw = RdLow<31:0> | RdHigh<31:0> << 32;}}, {{EXT_ASI}});
|
||||
}
|
||||
format LoadAlt {
|
||||
0x18: ldswa({{Rd = (int32_t)Mem.sw;}}, {{EXT_ASI}});
|
||||
@@ -1105,6 +1105,18 @@ decode OP default Unknown::unknown()
|
||||
0x15: FailUnimpl::lddfa_real_io();
|
||||
//ASI_REAL_IO_LITTLE
|
||||
0x1D: FailUnimpl::lddfa_real_io_l();
|
||||
//ASI_LDTX_REAL
|
||||
0x26: TwinLoad::ldtx_real(
|
||||
{{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
|
||||
//ASI_LDTX_N
|
||||
0x27: TwinLoad::ldtx_n(
|
||||
{{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
|
||||
//ASI_LDTX_REAL_L
|
||||
0x2E: TwinLoad::ldtx_real_l(
|
||||
{{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
|
||||
//ASI_LDTX_N_L
|
||||
0x2F: TwinLoad::ldtx_n_l(
|
||||
{{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
|
||||
//ASI_PRIMARY
|
||||
0x80: FailUnimpl::lddfa_p();
|
||||
//ASI_PRIMARY_LITTLE
|
||||
|
||||
@@ -91,6 +91,65 @@ output header {{
|
||||
};
|
||||
}};
|
||||
|
||||
output header {{
|
||||
|
||||
class TwinMem : public SparcMacroInst
|
||||
{
|
||||
protected:
|
||||
|
||||
// Constructor
|
||||
// We make the assumption that all block memory operations
|
||||
// Will take 8 instructions to execute
|
||||
TwinMem(const char *mnem, ExtMachInst _machInst) :
|
||||
SparcMacroInst(mnem, _machInst, No_OpClass, 8)
|
||||
{}
|
||||
};
|
||||
|
||||
class TwinMemImm : public BlockMem
|
||||
{
|
||||
protected:
|
||||
|
||||
// Constructor
|
||||
TwinMemImm(const char *mnem, ExtMachInst _machInst) :
|
||||
BlockMem(mnem, _machInst)
|
||||
{}
|
||||
};
|
||||
|
||||
class TwinMemMicro : public SparcMicroInst
|
||||
{
|
||||
protected:
|
||||
|
||||
// Constructor
|
||||
TwinMemMicro(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass, int8_t _offset) :
|
||||
SparcMicroInst(mnem, _machInst, __opClass),
|
||||
offset(_offset)
|
||||
{}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
|
||||
const int8_t offset;
|
||||
};
|
||||
|
||||
class TwinMemImmMicro : public BlockMemMicro
|
||||
{
|
||||
protected:
|
||||
|
||||
// Constructor
|
||||
TwinMemImmMicro(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
|
||||
@@ -149,6 +208,64 @@ output decoder {{
|
||||
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string TwinMemMicro::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 TwinMemImmMicro::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
|
||||
@@ -242,6 +359,39 @@ def template BlockMemDeclare {{
|
||||
};
|
||||
}};
|
||||
|
||||
def template TwinMemDeclare {{
|
||||
/**
|
||||
* 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
|
||||
};
|
||||
};
|
||||
}};
|
||||
|
||||
// Basic instruction class constructor template.
|
||||
def template BlockMemConstructor {{
|
||||
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||
@@ -259,6 +409,17 @@ def template BlockMemConstructor {{
|
||||
}
|
||||
}};
|
||||
|
||||
// Basic instruction class constructor template.
|
||||
def template TwinMemConstructor {{
|
||||
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);
|
||||
}
|
||||
}};
|
||||
|
||||
def template BlockMemMicroConstructor {{
|
||||
inline %(class_name)s::
|
||||
%(class_name)s_%(micro_pc)s::
|
||||
@@ -312,6 +473,47 @@ let {{
|
||||
asi, opt_flags);
|
||||
faultCode = ''
|
||||
return (header_output, decoder_output, exec_output, decode_block)
|
||||
|
||||
|
||||
def doTwinLoadFormat(code, faultCode, name, Name, asi, opt_flags):
|
||||
addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
|
||||
addrCalcImm = 'EA = Rs1 + imm + offset;'
|
||||
iop = InstObjParams(name, Name, 'TwinMem', code, opt_flags)
|
||||
iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', code, opt_flags)
|
||||
header_output = TwinMemDeclare.subst(iop) + TwinMemDeclare.subst(iop_imm)
|
||||
decoder_output = TwinMemConstructor.subst(iop) + TwinMemConstructor.subst(iop_imm)
|
||||
decode_block = ROrImmDecode.subst(iop)
|
||||
matcher = re.compile(r'RdTwin')
|
||||
exec_output = ''
|
||||
for microPc in range(2):
|
||||
flag_code = ''
|
||||
pcedCode = ''
|
||||
if (microPc == 1):
|
||||
flag_code = "flags[IsLastMicroOp] = true;"
|
||||
pcedCode = matcher.sub("RdHigh", code)
|
||||
else:
|
||||
flag_code = "flags[IsDelayedCommit] = true;"
|
||||
pcedCode = matcher.sub("RdLow", code)
|
||||
iop = InstObjParams(name, Name, 'TwinMem', pcedCode,
|
||||
opt_flags, {"ea_code": addrCalcReg,
|
||||
"fault_check": faultCode, "micro_pc": microPc,
|
||||
"set_flags": flag_code})
|
||||
iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', 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 += doDualSplitExecute(
|
||||
pcedCode, addrCalcReg, addrCalcImm, LoadExecute, faultCode,
|
||||
makeMicroName(name, microPc),
|
||||
makeMicroName(name + "Imm", microPc),
|
||||
makeMicroName(Name, microPc),
|
||||
makeMicroName(Name + "Imm", microPc),
|
||||
asi, opt_flags);
|
||||
faultCode = ''
|
||||
return (header_output, decoder_output, exec_output, decode_block)
|
||||
|
||||
}};
|
||||
|
||||
def format BlockLoad(code, asi, *opt_flags) {{
|
||||
@@ -337,3 +539,11 @@ def format BlockStore(code, asi, *opt_flags) {{
|
||||
decode_block) = doBlockMemFormat(code, faultCode,
|
||||
StoreFuncs, name, Name, asi, opt_flags)
|
||||
}};
|
||||
|
||||
def format TwinLoad(code, asi, *opt_flags) {{
|
||||
faultCode = AlternateASIPrivFaultCheck + TwinAlignmentFaultCheck
|
||||
(header_output,
|
||||
decoder_output,
|
||||
exec_output,
|
||||
decode_block) = doTwinLoadFormat(code, faultCode, name, Name, asi, opt_flags)
|
||||
}};
|
||||
|
||||
@@ -295,6 +295,12 @@ let {{
|
||||
else if(EA & 0x3f)
|
||||
fault = new MemAddressNotAligned;
|
||||
'''
|
||||
TwinAlignmentFaultCheck = '''
|
||||
if(RD & 0xe)
|
||||
fault = new IllegalInstruction;
|
||||
else if(EA & 0x1f)
|
||||
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
|
||||
|
||||
@@ -62,6 +62,9 @@ def operands {{
|
||||
'Rd_prev': ('IntReg', 'udw', 'RD + NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 2),
|
||||
# The Rd from the next window
|
||||
'Rd_next': ('IntReg', 'udw', 'RD + 2 * NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 3),
|
||||
# For microcoded twin load instructions, RdTwin appears in the "code"
|
||||
# for the instruction is replaced by RdLow or RdHigh by the format
|
||||
# before it's processed by the iop.
|
||||
# The low (even) register of a two register pair
|
||||
'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 4),
|
||||
# The high (odd) register of a two register pair
|
||||
|
||||
@@ -133,21 +133,21 @@ class SparcSystem : public System
|
||||
|
||||
/** Add a function-based event to reset binary. */
|
||||
template <class T>
|
||||
T *SparcSystem::addResetFuncEvent(const char *lbl)
|
||||
T *addResetFuncEvent(const char *lbl)
|
||||
{
|
||||
return addFuncEvent<T>(resetSymtab, lbl);
|
||||
}
|
||||
|
||||
/** Add a function-based event to the hypervisor. */
|
||||
template <class T>
|
||||
T *SparcSystem::addHypervisorFuncEvent(const char *lbl)
|
||||
T *addHypervisorFuncEvent(const char *lbl)
|
||||
{
|
||||
return addFuncEvent<T>(hypervisorSymtab, lbl);
|
||||
}
|
||||
|
||||
/** Add a function-based event to the openboot. */
|
||||
template <class T>
|
||||
T *SparcSystem::addOpenbootFuncEvent(const char *lbl)
|
||||
T *addOpenbootFuncEvent(const char *lbl)
|
||||
{
|
||||
return addFuncEvent<T>(openbootSymtab, lbl);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user