diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/arm/isa/decoder/arm.isa | 43 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/data.isa | 50 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/misc.isa | 48 |
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 }) |