ARM: Move some miscellaneous instructions out of the decoder to share with thumb.

This commit is contained in:
Gabe Black 2010-06-02 12:58:17 -05:00
parent 0e556e9dfb
commit 22d1a84509
3 changed files with 99 additions and 42 deletions

View file

@ -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 {

View file

@ -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 = '''
{

View file

@ -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 })