ARM: Move some miscellaneous instructions out of the decoder to share with thumb.
This commit is contained in:
parent
0e556e9dfb
commit
22d1a84509
3 changed files with 99 additions and 42 deletions
|
@ -81,48 +81,7 @@ format DataOp {
|
|||
}
|
||||
0x1: decode IS_MISC {
|
||||
0: ArmDataProcImm::armDataProcImm();
|
||||
1: decode OPCODE {
|
||||
// The following two instructions aren't supposed to be defined
|
||||
0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }});
|
||||
0x9: decode RN {
|
||||
0: decode IMM {
|
||||
0: PredImmOp::nop({{ ; }});
|
||||
#if FULL_SYSTEM
|
||||
1: PredImmOp::yield({{ ; }});
|
||||
2: PredImmOp::wfe({{
|
||||
if (SevMailbox)
|
||||
SevMailbox = 0;
|
||||
else
|
||||
PseudoInst::quiesce(xc->tcBase());
|
||||
}}, IsNonSpeculative, IsQuiesce);
|
||||
3: PredImmOp::wfi({{
|
||||
PseudoInst::quiesce(xc->tcBase());
|
||||
}}, IsNonSpeculative, IsQuiesce);
|
||||
4: PredImmOp::sev({{
|
||||
// Need a way for O3 to not scoreboard these
|
||||
// accesses as pipeflushs
|
||||
System *sys = xc->tcBase()->getSystemPtr();
|
||||
for (int x = 0; x < sys->numContexts(); x++) {
|
||||
ThreadContext *oc = sys->getThreadContext(x);
|
||||
oc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
|
||||
}
|
||||
}});
|
||||
#endif
|
||||
}
|
||||
default: PredImmOp::msr_i_cpsr({{
|
||||
SCTLR sctlr = Sctlr;
|
||||
uint32_t newCpsr =
|
||||
cpsrWriteByInstr(Cpsr | CondCodes,
|
||||
rotated_imm, RN, false, sctlr.nmfi);
|
||||
Cpsr = ~CondCodesMask & newCpsr;
|
||||
CondCodes = CondCodesMask & newCpsr;
|
||||
}});
|
||||
}
|
||||
0xa: PredOp::movt({{ Rd = IMMED_11_0 << 16 | RN << 28 | Rd<15:0>; }});
|
||||
0xb: PredImmOp::msr_i_spsr({{
|
||||
Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false);
|
||||
}});
|
||||
}
|
||||
1: ArmMisc::armMisc();
|
||||
}
|
||||
0x2: AddrMode2::addrMode2(True);
|
||||
0x3: decode OPCODE_4 {
|
||||
|
|
|
@ -1073,6 +1073,56 @@ def format Thumb16AddSp() {{
|
|||
'''
|
||||
}};
|
||||
|
||||
def format ArmMisc() {{
|
||||
decode_block = '''
|
||||
{
|
||||
const uint32_t unrotated = bits(machInst, 7, 0);
|
||||
const uint32_t rotation = (bits(machInst, 11, 8) << 1);
|
||||
const uint32_t imm = rotate_imm(unrotated, rotation);
|
||||
const uint8_t byteMask = bits(machInst, 19, 16);
|
||||
switch (OPCODE) {
|
||||
case 0x8:
|
||||
return new MovImm(machInst, (IntRegIndex)(uint32_t)RD,
|
||||
(IntRegIndex)INTREG_ZERO,
|
||||
bits(machInst, 11, 0) | (bits(machInst, 19, 16) << 12),
|
||||
false);
|
||||
case 0x9:
|
||||
if (RN == 0) {
|
||||
switch (IMM) {
|
||||
case 0x0:
|
||||
return new NopInst(machInst);
|
||||
#if FULL_SYSTEM
|
||||
case 0x1:
|
||||
return new YieldInst(machInst);
|
||||
case 0x2:
|
||||
return new WfeInst(machInst);
|
||||
case 0x3:
|
||||
return new WfiInst(machInst);
|
||||
case 0x4:
|
||||
return new SevInst(machInst);
|
||||
#endif
|
||||
default:
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
} else {
|
||||
return new MsrCpsrImm(machInst, imm, byteMask);
|
||||
}
|
||||
case 0xa:
|
||||
{
|
||||
const uint32_t timm = (bits(machInst, 19, 16) << 12) |
|
||||
bits(machInst, 11, 0);
|
||||
return new MovtImm(machInst, (IntRegIndex)(uint32_t)RD,
|
||||
(IntRegIndex)(uint32_t)RD, timm, true);
|
||||
}
|
||||
case 0xb:
|
||||
return new MsrSpsrImm(machInst, imm, byteMask);
|
||||
default:
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
}
|
||||
'''
|
||||
}};
|
||||
|
||||
def format Thumb16Misc() {{
|
||||
decode_block = '''
|
||||
{
|
||||
|
|
|
@ -468,6 +468,54 @@ let {{
|
|||
decoder_output += BasicConstructor.subst(nopIop)
|
||||
exec_output += PredOpExecute.subst(nopIop)
|
||||
|
||||
yieldIop = InstObjParams("yield", "YieldInst", "PredOp", \
|
||||
{ "code" : "", "predicate_test" : predicateTest })
|
||||
header_output += BasicDeclare.subst(yieldIop)
|
||||
decoder_output += BasicConstructor.subst(yieldIop)
|
||||
exec_output += PredOpExecute.subst(yieldIop)
|
||||
|
||||
wfeCode = '''
|
||||
#if FULL_SYSTEM
|
||||
if (SevMailbox)
|
||||
SevMailbox = 0;
|
||||
else
|
||||
PseudoInst::quiesce(xc->tcBase());
|
||||
#endif
|
||||
'''
|
||||
wfeIop = InstObjParams("wfe", "WfeInst", "PredOp", \
|
||||
{ "code" : wfeCode, "predicate_test" : predicateTest },
|
||||
["IsNonSpeculative", "IsQuiesce"])
|
||||
header_output += BasicDeclare.subst(wfeIop)
|
||||
decoder_output += BasicConstructor.subst(wfeIop)
|
||||
exec_output += PredOpExecute.subst(wfeIop)
|
||||
|
||||
wfiCode = '''
|
||||
#if FULL_SYSTEM
|
||||
PseudoInst::quiesce(xc->tcBase());
|
||||
#endif
|
||||
'''
|
||||
wfiIop = InstObjParams("wfi", "WfiInst", "PredOp", \
|
||||
{ "code" : wfiCode, "predicate_test" : predicateTest },
|
||||
["IsNonSpeculative", "IsQuiesce"])
|
||||
header_output += BasicDeclare.subst(wfiIop)
|
||||
decoder_output += BasicConstructor.subst(wfiIop)
|
||||
exec_output += PredOpExecute.subst(wfiIop)
|
||||
|
||||
sevCode = '''
|
||||
// Need a way for O3 to not scoreboard these accesses as pipe flushes.
|
||||
System *sys = xc->tcBase()->getSystemPtr();
|
||||
for (int x = 0; x < sys->numContexts(); x++) {
|
||||
ThreadContext *oc = sys->getThreadContext(x);
|
||||
oc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
|
||||
}
|
||||
'''
|
||||
sevIop = InstObjParams("sev", "SevInst", "PredOp", \
|
||||
{ "code" : sevCode, "predicate_test" : predicateTest },
|
||||
["IsNonSpeculative", "IsQuiesce"])
|
||||
header_output += BasicDeclare.subst(sevIop)
|
||||
decoder_output += BasicConstructor.subst(sevIop)
|
||||
exec_output += PredOpExecute.subst(sevIop)
|
||||
|
||||
itIop = InstObjParams("it", "ItInst", "PredOp", \
|
||||
{ "code" : "Itstate = machInst.newItstate;",
|
||||
"predicate_test" : predicateTest })
|
||||
|
|
Loading…
Reference in a new issue