diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2010-06-02 12:58:16 -0500 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2010-06-02 12:58:16 -0500 |
commit | 05bd3eb4ec3d9fea3dbc46112a47459085d3011c (patch) | |
tree | 58d50fab58de1e9165bfc28986913811b26b9568 /src/arch/arm/isa | |
parent | b93ceef5381b7c84b6887b5299ae81ff48ef45c9 (diff) | |
download | gem5-05bd3eb4ec3d9fea3dbc46112a47459085d3011c.tar.xz |
ARM: Implement support for the IT instruction and the ITSTATE bits of CPSR.
Diffstat (limited to 'src/arch/arm/isa')
-rw-r--r-- | src/arch/arm/isa/formats/data.isa | 148 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/macromem.isa | 4 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/misc.isa | 12 | ||||
-rw-r--r-- | src/arch/arm/isa/operands.isa | 1 | ||||
-rw-r--r-- | src/arch/arm/isa/templates/mem.isa | 44 | ||||
-rw-r--r-- | src/arch/arm/isa/templates/pred.isa | 10 |
6 files changed, 188 insertions, 31 deletions
diff --git a/src/arch/arm/isa/formats/data.isa b/src/arch/arm/isa/formats/data.isa index 3e6265d0b..a1d0c53a2 100644 --- a/src/arch/arm/isa/formats/data.isa +++ b/src/arch/arm/isa/formats/data.isa @@ -852,30 +852,70 @@ def format Thumb16ShiftAddSubMoveCmp() {{ const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6); switch (bits(machInst, 13, 11)) { case 0x0: // lsl - return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL); + if (machInst.itstateMask) { + return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSL); + } else { + return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL); + } case 0x1: // lsr - return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR); + if (machInst.itstateMask) { + return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSR); + } else { + return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR); + } case 0x2: // asr - return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR); + if (machInst.itstateMask) { + return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, ASR); + } else { + return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR); + } case 0x3: switch (bits(machInst, 10, 9)) { case 0x0: - return new AddRegCc(machInst, rd, rn, rm, 0, LSL); + if (machInst.itstateMask) { + return new AddReg(machInst, rd, rn, rm, 0, LSL); + } else { + return new AddRegCc(machInst, rd, rn, rm, 0, LSL); + } case 0x1: - return new SubRegCc(machInst, rd, rn, rm, 0, LSL); + if (machInst.itstateMask) { + return new SubReg(machInst, rd, rn, rm, 0, LSL); + } else { + return new SubRegCc(machInst, rd, rn, rm, 0, LSL); + } case 0x2: - return new AddImmCc(machInst, rd, rn, imm3, true); + if (machInst.itstateMask) { + return new AddImm(machInst, rd, rn, imm3, true); + } else { + return new AddImmCc(machInst, rd, rn, imm3, true); + } case 0x3: - return new SubImmCc(machInst, rd, rn, imm3, true); + if (machInst.itstateMask) { + return new SubImm(machInst, rd, rn, imm3, true); + } else { + return new SubImmCc(machInst, rd, rn, imm3, true); + } } case 0x4: - return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false); + if (machInst.itstateMask) { + return new MovImm(machInst, rd8, INTREG_ZERO, imm8, false); + } else { + return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false); + } case 0x5: return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true); case 0x6: - return new AddImmCc(machInst, rd8, rd8, imm8, true); + if (machInst.itstateMask) { + return new AddImm(machInst, rd8, rd8, imm8, true); + } else { + return new AddImmCc(machInst, rd8, rd8, imm8, true); + } case 0x7: - return new SubImmCc(machInst, rd8, rd8, imm8, true); + if (machInst.itstateMask) { + return new SubImm(machInst, rd8, rd8, imm8, true); + } else { + return new SubImmCc(machInst, rd8, rd8, imm8, true); + } } } ''' @@ -888,37 +928,97 @@ def format Thumb16DataProcessing() {{ const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); switch (bits(machInst, 9, 6)) { case 0x0: - return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL); + if (machInst.itstateMask) { + return new AndReg(machInst, rdn, rdn, rm, 0, LSL); + } else { + return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL); + } case 0x1: - return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL); + if (machInst.itstateMask) { + return new EorReg(machInst, rdn, rdn, rm, 0, LSL); + } else { + return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL); + } case 0x2: //lsl - return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL); + if (machInst.itstateMask) { + return new MovRegReg(machInst, rdn, + INTREG_ZERO, rdn, rm, LSL); + } else { + return new MovRegRegCc(machInst, rdn, + INTREG_ZERO, rdn, rm, LSL); + } case 0x3: //lsr - return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR); + if (machInst.itstateMask) { + return new MovRegReg(machInst, rdn, + INTREG_ZERO, rdn, rm, LSR); + } else { + return new MovRegRegCc(machInst, rdn, + INTREG_ZERO, rdn, rm, LSR); + } case 0x4: //asr - return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR); + if (machInst.itstateMask) { + return new MovRegReg(machInst, rdn, + INTREG_ZERO, rdn, rm, ASR); + } else { + return new MovRegRegCc(machInst, rdn, + INTREG_ZERO, rdn, rm, ASR); + } case 0x5: - return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL); + if (machInst.itstateMask) { + return new AdcReg(machInst, rdn, rdn, rm, 0, LSL); + } else { + return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL); + } case 0x6: - return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL); + if (machInst.itstateMask) { + return new SbcReg(machInst, rdn, rdn, rm, 0, LSL); + } else { + return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL); + } case 0x7: // ror - return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR); + if (machInst.itstateMask) { + return new MovRegReg(machInst, rdn, + INTREG_ZERO, rdn, rm, ROR); + } else { + return new MovRegRegCc(machInst, rdn, + INTREG_ZERO, rdn, rm, ROR); + } case 0x8: return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); case 0x9: - return new RsbImmCc(machInst, rdn, rm, 0, true); + if (machInst.itstateMask) { + return new RsbImm(machInst, rdn, rm, 0, true); + } else { + return new RsbImmCc(machInst, rdn, rm, 0, true); + } case 0xa: return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); case 0xb: return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); case 0xc: - return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL); + if (machInst.itstateMask) { + return new OrrReg(machInst, rdn, rdn, rm, 0, LSL); + } else { + return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL); + } case 0xd: - return new MulCc(machInst, rdn, rm, rdn); + if (machInst.itstateMask) { + return new Mul(machInst, rdn, rm, rdn); + } else { + return new MulCc(machInst, rdn, rm, rdn); + } case 0xe: - return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL); + if (machInst.itstateMask) { + return new BicReg(machInst, rdn, rdn, rm, 0, LSL); + } else { + return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL); + } case 0xf: - return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL); + if (machInst.itstateMask) { + return new MvnReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL); + } else { + return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL); + } } } ''' @@ -1070,7 +1170,7 @@ def format Thumb16Misc() {{ return new WarnUnimplemented("bkpt", machInst); case 0xf: if (bits(machInst, 3, 0) != 0) - return new WarnUnimplemented("it", machInst); + return new ItInst(machInst); switch (bits(machInst, 7, 4)) { case 0x0: return new NopInst(machInst); diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa index 82e9d9842..2b42dfac8 100644 --- a/src/arch/arm/isa/insts/macromem.isa +++ b/src/arch/arm/isa/insts/macromem.isa @@ -47,10 +47,6 @@ // let {{ - predicateTest = 'testPredicate(CondCodes, condCode)' -}}; - -let {{ microLdrUopCode = "IWRa = cSwap(Mem.uw, ((CPSR)Cpsr).e);" microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop', 'MicroMemOp', diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index 722b05eac..ee6330f48 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -456,10 +456,18 @@ let {{ decoder_output += RegRegRegRegOpConstructor.subst(usada8Iop) exec_output += PredOpExecute.subst(usada8Iop) - nopIop = InstObjParams("nop", "NopInst", "ArmStaticInst", "", []) + nopIop = InstObjParams("nop", "NopInst", "PredOp", \ + { "code" : "", "predicate_test" : predicateTest }) header_output += BasicDeclare.subst(nopIop) decoder_output += BasicConstructor.subst(nopIop) - exec_output += BasicExecute.subst(nopIop) + exec_output += PredOpExecute.subst(nopIop) + + itIop = InstObjParams("it", "ItInst", "PredOp", \ + { "code" : "Itstate = machInst.newItstate;", + "predicate_test" : predicateTest }) + header_output += BasicDeclare.subst(itIop) + decoder_output += BasicConstructor.subst(itIop) + exec_output += PredOpExecute.subst(itIop) ubfxCode = ''' Dest = bits(Op1, imm2, imm1); diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 4c269276a..b041cef43 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -171,6 +171,7 @@ def operands {{ 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 2), 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', (None, None, 'IsControl'), 1), + 'Itstate': ('ControlReg', 'ub', 'MISCREG_ITSTATE', None, 2), 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', None, 2), 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', None, 2), 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', None, 2), diff --git a/src/arch/arm/isa/templates/mem.isa b/src/arch/arm/isa/templates/mem.isa index 983d99af9..4f1235b03 100644 --- a/src/arch/arm/isa/templates/mem.isa +++ b/src/arch/arm/isa/templates/mem.isa @@ -71,6 +71,10 @@ def template SwapExecute {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; @@ -101,6 +105,10 @@ def template SwapInitiateAcc {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; @@ -127,6 +135,10 @@ def template SwapCompleteAcc {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; @@ -154,6 +166,10 @@ def template LoadExecute {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; @@ -186,6 +202,10 @@ def template StoreExecute {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; @@ -224,6 +244,10 @@ def template StoreExExecute {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; @@ -257,6 +281,10 @@ def template StoreExInitiateAcc {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; @@ -290,6 +318,10 @@ def template StoreInitiateAcc {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; @@ -340,6 +372,10 @@ def template LoadCompleteAcc {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; @@ -361,6 +397,10 @@ def template StoreCompleteAcc {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; @@ -385,6 +425,10 @@ def template StoreExCompleteAcc {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; diff --git a/src/arch/arm/isa/templates/pred.isa b/src/arch/arm/isa/templates/pred.isa index 15d34da19..c8f30ddf0 100644 --- a/src/arch/arm/isa/templates/pred.isa +++ b/src/arch/arm/isa/templates/pred.isa @@ -46,7 +46,11 @@ // let {{ - predicateTest = 'testPredicate(CondCodes, condCode)' + predicateTest = ''' + testPredicate(CondCodes, machInst.itstateMask ? + (ConditionCode)(uint8_t)machInst.itstateCond : + condCode) + ''' }}; def template DataImmDeclare {{ @@ -143,6 +147,10 @@ def template PredOpExecute {{ } } + if (fault == NoFault && machInst.itstateMask != 0) { + xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); + } + return fault; } }}; |