summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/isa/decoder/arm.isa43
-rw-r--r--src/arch/arm/isa/formats/data.isa50
-rw-r--r--src/arch/arm/isa/insts/misc.isa48
3 files changed, 99 insertions, 42 deletions
diff --git a/src/arch/arm/isa/decoder/arm.isa b/src/arch/arm/isa/decoder/arm.isa
index 49f70e5e4..29ec46f9b 100644
--- a/src/arch/arm/isa/decoder/arm.isa
+++ b/src/arch/arm/isa/decoder/arm.isa
@@ -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 {
diff --git a/src/arch/arm/isa/formats/data.isa b/src/arch/arm/isa/formats/data.isa
index e97769835..a567a92b4 100644
--- a/src/arch/arm/isa/formats/data.isa
+++ b/src/arch/arm/isa/formats/data.isa
@@ -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 = '''
{
diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa
index 64bff6cb1..7f9a5c171 100644
--- a/src/arch/arm/isa/insts/misc.isa
+++ b/src/arch/arm/isa/insts/misc.isa
@@ -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 })