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 {
|
0x1: decode IS_MISC {
|
||||||
0: ArmDataProcImm::armDataProcImm();
|
0: ArmDataProcImm::armDataProcImm();
|
||||||
1: decode OPCODE {
|
1: ArmMisc::armMisc();
|
||||||
// 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);
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
0x2: AddrMode2::addrMode2(True);
|
0x2: AddrMode2::addrMode2(True);
|
||||||
0x3: decode OPCODE_4 {
|
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() {{
|
def format Thumb16Misc() {{
|
||||||
decode_block = '''
|
decode_block = '''
|
||||||
{
|
{
|
||||||
|
|
|
@ -468,6 +468,54 @@ let {{
|
||||||
decoder_output += BasicConstructor.subst(nopIop)
|
decoder_output += BasicConstructor.subst(nopIop)
|
||||||
exec_output += PredOpExecute.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", \
|
itIop = InstObjParams("it", "ItInst", "PredOp", \
|
||||||
{ "code" : "Itstate = machInst.newItstate;",
|
{ "code" : "Itstate = machInst.newItstate;",
|
||||||
"predicate_test" : predicateTest })
|
"predicate_test" : predicateTest })
|
||||||
|
|
Loading…
Reference in a new issue