static_inst.cc revision 11793:ef606668d247
1/*
2 * Copyright (c) 2010-2014, 2016 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder.  You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2007-2008 The Florida State University
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Stephen Hines
42 */
43
44#include "arch/arm/insts/static_inst.hh"
45
46#include "arch/arm/faults.hh"
47#include "base/condcodes.hh"
48#include "base/cprintf.hh"
49#include "base/loader/symtab.hh"
50#include "cpu/reg_class.hh"
51
52namespace ArmISA
53{
54// Shift Rm by an immediate value
55int32_t
56ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt,
57                                uint32_t type, uint32_t cfval) const
58{
59    assert(shamt < 32);
60    ArmShiftType shiftType;
61    shiftType = (ArmShiftType)type;
62
63    switch (shiftType)
64    {
65      case LSL:
66        return base << shamt;
67      case LSR:
68        if (shamt == 0)
69            return 0;
70        else
71            return base >> shamt;
72      case ASR:
73        if (shamt == 0)
74            return (base >> 31) | -((base & (1 << 31)) >> 31);
75        else
76            return (base >> shamt) | -((base & (1 << 31)) >> shamt);
77      case ROR:
78        if (shamt == 0)
79            return (cfval << 31) | (base >> 1); // RRX
80        else
81            return (base << (32 - shamt)) | (base >> shamt);
82      default:
83        ccprintf(std::cerr, "Unhandled shift type\n");
84        exit(1);
85        break;
86    }
87    return 0;
88}
89
90int64_t
91ArmStaticInst::shiftReg64(uint64_t base, uint64_t shiftAmt,
92                          ArmShiftType type, uint8_t width) const
93{
94    shiftAmt = shiftAmt % width;
95    ArmShiftType shiftType;
96    shiftType = (ArmShiftType)type;
97
98    switch (shiftType)
99    {
100      case LSL:
101        return base << shiftAmt;
102      case LSR:
103        if (shiftAmt == 0)
104            return base;
105        else
106            return (base & mask(width)) >> shiftAmt;
107      case ASR:
108        if (shiftAmt == 0) {
109            return base;
110        } else {
111            int sign_bit = bits(base, intWidth - 1);
112            base >>= shiftAmt;
113            base = sign_bit ? (base | ~mask(intWidth - shiftAmt)) : base;
114            return base & mask(intWidth);
115        }
116      case ROR:
117        if (shiftAmt == 0)
118            return base;
119        else
120            return (base << (width - shiftAmt)) | (base >> shiftAmt);
121      default:
122        ccprintf(std::cerr, "Unhandled shift type\n");
123        exit(1);
124        break;
125    }
126    return 0;
127}
128
129int64_t
130ArmStaticInst::extendReg64(uint64_t base, ArmExtendType type,
131                           uint64_t shiftAmt, uint8_t width) const
132{
133    bool sign_extend = false;
134    int len = 0;
135    switch (type) {
136      case UXTB:
137        len = 8;
138        break;
139      case UXTH:
140        len = 16;
141        break;
142      case UXTW:
143        len = 32;
144        break;
145      case UXTX:
146        len = 64;
147        break;
148      case SXTB:
149        len = 8;
150        sign_extend = true;
151        break;
152      case SXTH:
153        len = 16;
154        sign_extend = true;
155        break;
156      case SXTW:
157        len = 32;
158        sign_extend = true;
159        break;
160      case SXTX:
161        len = 64;
162        sign_extend = true;
163        break;
164    }
165    len = len <= width - shiftAmt ? len : width - shiftAmt;
166    uint64_t tmp = (uint64_t) bits(base, len - 1, 0) << shiftAmt;
167    if (sign_extend) {
168        int sign_bit = bits(tmp, len + shiftAmt - 1);
169        tmp = sign_bit ? (tmp | ~mask(len + shiftAmt)) : tmp;
170    }
171    return tmp & mask(width);
172}
173
174// Shift Rm by Rs
175int32_t
176ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt,
177                               uint32_t type, uint32_t cfval) const
178{
179    enum ArmShiftType shiftType;
180    shiftType = (enum ArmShiftType) type;
181
182    switch (shiftType)
183    {
184      case LSL:
185        if (shamt >= 32)
186            return 0;
187        else
188            return base << shamt;
189      case LSR:
190        if (shamt >= 32)
191            return 0;
192        else
193            return base >> shamt;
194      case ASR:
195        if (shamt >= 32)
196            return (base >> 31) | -((base & (1 << 31)) >> 31);
197        else
198            return (base >> shamt) | -((base & (1 << 31)) >> shamt);
199      case ROR:
200        shamt = shamt & 0x1f;
201        if (shamt == 0)
202            return base;
203        else
204            return (base << (32 - shamt)) | (base >> shamt);
205      default:
206        ccprintf(std::cerr, "Unhandled shift type\n");
207        exit(1);
208        break;
209    }
210    return 0;
211}
212
213
214// Generate C for a shift by immediate
215bool
216ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt,
217                                   uint32_t type, uint32_t cfval) const
218{
219    enum ArmShiftType shiftType;
220    shiftType = (enum ArmShiftType) type;
221
222    switch (shiftType)
223    {
224      case LSL:
225        if (shamt == 0)
226            return cfval;
227        else
228            return (base >> (32 - shamt)) & 1;
229      case LSR:
230        if (shamt == 0)
231            return (base >> 31);
232        else
233            return (base >> (shamt - 1)) & 1;
234      case ASR:
235        if (shamt == 0)
236            return (base >> 31);
237        else
238            return (base >> (shamt - 1)) & 1;
239      case ROR:
240        shamt = shamt & 0x1f;
241        if (shamt == 0)
242            return (base & 1); // RRX
243        else
244            return (base >> (shamt - 1)) & 1;
245      default:
246        ccprintf(std::cerr, "Unhandled shift type\n");
247        exit(1);
248        break;
249    }
250    return 0;
251}
252
253
254// Generate C for a shift by Rs
255bool
256ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
257                                  uint32_t type, uint32_t cfval) const
258{
259    enum ArmShiftType shiftType;
260    shiftType = (enum ArmShiftType) type;
261
262    if (shamt == 0)
263        return cfval;
264
265    switch (shiftType)
266    {
267      case LSL:
268        if (shamt > 32)
269            return 0;
270        else
271            return (base >> (32 - shamt)) & 1;
272      case LSR:
273        if (shamt > 32)
274            return 0;
275        else
276            return (base >> (shamt - 1)) & 1;
277      case ASR:
278        if (shamt > 32)
279            shamt = 32;
280        return (base >> (shamt - 1)) & 1;
281      case ROR:
282        shamt = shamt & 0x1f;
283        if (shamt == 0)
284            shamt = 32;
285        return (base >> (shamt - 1)) & 1;
286      default:
287        ccprintf(std::cerr, "Unhandled shift type\n");
288        exit(1);
289        break;
290    }
291    return 0;
292}
293
294
295void
296ArmStaticInst::printReg(std::ostream &os, int reg) const
297{
298    RegIndex rel_reg;
299
300    switch (regIdxToClass(reg, &rel_reg)) {
301      case IntRegClass:
302        if (aarch64) {
303            if (reg == INTREG_UREG0)
304                ccprintf(os, "ureg0");
305            else if (reg == INTREG_SPX)
306               ccprintf(os, "%s%s", (intWidth == 32) ? "w" : "", "sp");
307            else if (reg == INTREG_X31)
308                ccprintf(os, "%szr", (intWidth == 32) ? "w" : "x");
309            else
310                ccprintf(os, "%s%d", (intWidth == 32) ? "w" : "x", reg);
311        } else {
312            switch (rel_reg) {
313              case PCReg:
314                ccprintf(os, "pc");
315                break;
316              case StackPointerReg:
317                ccprintf(os, "sp");
318                break;
319              case FramePointerReg:
320                ccprintf(os, "fp");
321                break;
322              case ReturnAddressReg:
323                ccprintf(os, "lr");
324                break;
325              default:
326                ccprintf(os, "r%d", reg);
327                break;
328            }
329        }
330        break;
331      case FloatRegClass:
332        ccprintf(os, "f%d", rel_reg);
333        break;
334      case MiscRegClass:
335        assert(rel_reg < NUM_MISCREGS);
336        ccprintf(os, "%s", ArmISA::miscRegName[rel_reg]);
337        break;
338      case CCRegClass:
339        ccprintf(os, "cc_%s", ArmISA::ccRegName[rel_reg]);
340        break;
341    }
342}
343
344void
345ArmStaticInst::printMnemonic(std::ostream &os,
346                             const std::string &suffix,
347                             bool withPred,
348                             bool withCond64,
349                             ConditionCode cond64) const
350{
351    os << "  " << mnemonic;
352    if (withPred && !aarch64) {
353        printCondition(os, machInst.condCode);
354        os << suffix;
355    } else if (withCond64) {
356        os << ".";
357        printCondition(os, cond64);
358        os << suffix;
359    }
360    if (machInst.bigThumb)
361        os << ".w";
362    os << "   ";
363}
364
365void
366ArmStaticInst::printTarget(std::ostream &os, Addr target,
367                           const SymbolTable *symtab) const
368{
369    Addr symbolAddr;
370    std::string symbol;
371
372    if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) {
373        ccprintf(os, "<%s", symbol);
374        if (symbolAddr != target)
375            ccprintf(os, "+%d>", target - symbolAddr);
376        else
377            ccprintf(os, ">");
378    } else {
379        ccprintf(os, "%#x", target);
380    }
381}
382
383void
384ArmStaticInst::printCondition(std::ostream &os,
385                              unsigned code,
386                              bool noImplicit) const
387{
388    switch (code) {
389      case COND_EQ:
390        os << "eq";
391        break;
392      case COND_NE:
393        os << "ne";
394        break;
395      case COND_CS:
396        os << "cs";
397        break;
398      case COND_CC:
399        os << "cc";
400        break;
401      case COND_MI:
402        os << "mi";
403        break;
404      case COND_PL:
405        os << "pl";
406        break;
407      case COND_VS:
408        os << "vs";
409        break;
410      case COND_VC:
411        os << "vc";
412        break;
413      case COND_HI:
414        os << "hi";
415        break;
416      case COND_LS:
417        os << "ls";
418        break;
419      case COND_GE:
420        os << "ge";
421        break;
422      case COND_LT:
423        os << "lt";
424        break;
425      case COND_GT:
426        os << "gt";
427        break;
428      case COND_LE:
429        os << "le";
430        break;
431      case COND_AL:
432        // This one is implicit.
433        if (noImplicit)
434            os << "al";
435        break;
436      case COND_UC:
437        // Unconditional.
438        if (noImplicit)
439            os << "uc";
440        break;
441      default:
442        panic("Unrecognized condition code %d.\n", code);
443    }
444}
445
446void
447ArmStaticInst::printMemSymbol(std::ostream &os,
448                              const SymbolTable *symtab,
449                              const std::string &prefix,
450                              const Addr addr,
451                              const std::string &suffix) const
452{
453    Addr symbolAddr;
454    std::string symbol;
455    if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
456        ccprintf(os, "%s%s", prefix, symbol);
457        if (symbolAddr != addr)
458            ccprintf(os, "+%d", addr - symbolAddr);
459        ccprintf(os, suffix);
460    }
461}
462
463void
464ArmStaticInst::printShiftOperand(std::ostream &os,
465                                     IntRegIndex rm,
466                                     bool immShift,
467                                     uint32_t shiftAmt,
468                                     IntRegIndex rs,
469                                     ArmShiftType type) const
470{
471    bool firstOp = false;
472
473    if (rm != INTREG_ZERO) {
474        printReg(os, rm);
475    }
476
477    bool done = false;
478
479    if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
480        shiftAmt = 32;
481
482    switch (type) {
483      case LSL:
484        if (immShift && shiftAmt == 0) {
485            done = true;
486            break;
487        }
488        if (!firstOp)
489            os << ", ";
490        os << "LSL";
491        break;
492      case LSR:
493        if (!firstOp)
494            os << ", ";
495        os << "LSR";
496        break;
497      case ASR:
498        if (!firstOp)
499            os << ", ";
500        os << "ASR";
501        break;
502      case ROR:
503        if (immShift && shiftAmt == 0) {
504            if (!firstOp)
505                os << ", ";
506            os << "RRX";
507            done = true;
508            break;
509        }
510        if (!firstOp)
511            os << ", ";
512        os << "ROR";
513        break;
514      default:
515        panic("Tried to disassemble unrecognized shift type.\n");
516    }
517    if (!done) {
518        if (!firstOp)
519            os << " ";
520        if (immShift)
521            os << "#" << shiftAmt;
522        else
523            printReg(os, rs);
524    }
525}
526
527void
528ArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os,
529                                  IntRegIndex rm, ArmExtendType type,
530                                  int64_t shiftAmt) const
531{
532    if (!firstOperand)
533        ccprintf(os, ", ");
534    printReg(os, rm);
535    if (type == UXTX && shiftAmt == 0)
536        return;
537    switch (type) {
538      case UXTB: ccprintf(os, ", UXTB");
539        break;
540      case UXTH: ccprintf(os, ", UXTH");
541        break;
542      case UXTW: ccprintf(os, ", UXTW");
543        break;
544      case UXTX: ccprintf(os, ", LSL");
545        break;
546      case SXTB: ccprintf(os, ", SXTB");
547        break;
548      case SXTH: ccprintf(os, ", SXTH");
549        break;
550      case SXTW: ccprintf(os, ", SXTW");
551        break;
552      case SXTX: ccprintf(os, ", SXTW");
553        break;
554    }
555    if (type == UXTX || shiftAmt)
556        ccprintf(os, " #%d", shiftAmt);
557}
558
559void
560ArmStaticInst::printDataInst(std::ostream &os, bool withImm,
561        bool immShift, bool s, IntRegIndex rd, IntRegIndex rn,
562        IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt,
563        ArmShiftType type, uint64_t imm) const
564{
565    printMnemonic(os, s ? "s" : "");
566    bool firstOp = true;
567
568    // Destination
569    if (rd != INTREG_ZERO) {
570        firstOp = false;
571        printReg(os, rd);
572    }
573
574    // Source 1.
575    if (rn != INTREG_ZERO) {
576        if (!firstOp)
577            os << ", ";
578        firstOp = false;
579        printReg(os, rn);
580    }
581
582    if (!firstOp)
583        os << ", ";
584    if (withImm) {
585        ccprintf(os, "#%ld", imm);
586    } else {
587        printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
588    }
589}
590
591std::string
592ArmStaticInst::generateDisassembly(Addr pc,
593                                   const SymbolTable *symtab) const
594{
595    std::stringstream ss;
596    printMnemonic(ss);
597    return ss.str();
598}
599
600
601Fault
602ArmStaticInst::advSIMDFPAccessTrap64(ExceptionLevel el) const
603{
604    switch (el) {
605      case EL1:
606        return std::make_shared<SupervisorTrap>(machInst, 0x1E00000,
607                                                EC_TRAPPED_SIMD_FP);
608      case EL2:
609        return std::make_shared<HypervisorTrap>(machInst, 0x1E00000,
610                                                EC_TRAPPED_SIMD_FP);
611      case EL3:
612        return std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000,
613                                                   EC_TRAPPED_SIMD_FP);
614
615      default:
616        panic("Illegal EL in advSIMDFPAccessTrap64\n");
617    }
618}
619
620
621Fault
622ArmStaticInst::checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const
623{
624    const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el;
625
626    if (ArmSystem::haveVirtualization(tc) && el <= EL2) {
627        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL2);
628        if (cptrEnCheck.tfp)
629            return advSIMDFPAccessTrap64(EL2);
630    }
631
632    if (ArmSystem::haveSecurity(tc)) {
633        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3);
634        if (cptrEnCheck.tfp)
635            return advSIMDFPAccessTrap64(EL3);
636    }
637
638    return NoFault;
639}
640
641Fault
642ArmStaticInst::checkFPAdvSIMDEnabled64(ThreadContext *tc,
643                                       CPSR cpsr, CPACR cpacr) const
644{
645    const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el;
646    if ((el == EL0 && cpacr.fpen != 0x3) ||
647        (el == EL1 && !(cpacr.fpen & 0x1)))
648        return advSIMDFPAccessTrap64(EL1);
649
650    return checkFPAdvSIMDTrap64(tc, cpsr);
651}
652
653Fault
654ArmStaticInst::checkAdvSIMDOrFPEnabled32(ThreadContext *tc,
655                                         CPSR cpsr, CPACR cpacr,
656                                         NSACR nsacr, FPEXC fpexc,
657                                         bool fpexc_check, bool advsimd) const
658{
659    const bool have_virtualization = ArmSystem::haveVirtualization(tc);
660    const bool have_security = ArmSystem::haveSecurity(tc);
661    const bool is_secure = inSecureState(tc);
662    const ExceptionLevel cur_el = opModeToEL(currOpMode(tc));
663
664    if (cur_el == EL0 && ELIs64(tc, EL1))
665        return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr);
666
667    uint8_t cpacr_cp10 = cpacr.cp10;
668    bool cpacr_asedis = cpacr.asedis;
669
670    if (have_security && !ELIs64(tc, EL3) && !is_secure) {
671        if (nsacr.nsasedis)
672            cpacr_asedis = true;
673        if (nsacr.cp10 == 0)
674            cpacr_cp10 = 0;
675    }
676
677    if (cur_el != EL2) {
678        if (advsimd && cpacr_asedis)
679            return disabledFault();
680
681        if ((cur_el == EL0 && cpacr_cp10 != 0x3) ||
682            (cur_el != EL0 && !(cpacr_cp10 & 0x1)))
683            return disabledFault();
684    }
685
686    if (fpexc_check && !fpexc.en)
687        return disabledFault();
688
689    // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap --
690
691    if (have_virtualization && !is_secure && ELIs64(tc, EL2))
692        return checkFPAdvSIMDTrap64(tc, cpsr);
693
694    if (have_virtualization && !is_secure) {
695        HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR);
696        bool hcptr_cp10 = hcptr.tcp10;
697        bool hcptr_tase = hcptr.tase;
698
699        if (have_security && !ELIs64(tc, EL3) && !is_secure) {
700            if (nsacr.nsasedis)
701                hcptr_tase = true;
702            if (nsacr.cp10)
703                hcptr_cp10 = true;
704        }
705
706        if ((advsimd && hcptr_tase) || hcptr_cp10) {
707            const uint32_t iss = advsimd ? (1 << 5) : 0xA;
708            if (cur_el == EL2) {
709                return std::make_shared<UndefinedInstruction>(
710                    machInst, iss,
711                    EC_TRAPPED_HCPTR, mnemonic);
712            } else {
713                return std::make_shared<HypervisorTrap>(
714                    machInst, iss,
715                    EC_TRAPPED_HCPTR);
716            }
717
718        }
719    }
720
721    if (have_security && ELIs64(tc, EL3)) {
722        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3);
723        if (cptrEnCheck.tfp)
724            return advSIMDFPAccessTrap64(EL3);
725    }
726
727    return NoFault;
728}
729
730
731static uint8_t
732getRestoredITBits(ThreadContext *tc, CPSR spsr)
733{
734    // See: shared/functions/system/RestoredITBits in the ARM ARM
735
736    const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode);
737    const uint8_t it = itState(spsr);
738
739    if (!spsr.t || spsr.il)
740        return 0;
741
742    // The IT bits are forced to zero when they are set to a reserved
743    // value.
744    if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0)
745        return 0;
746
747    const bool itd = el == EL2 ?
748        ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd :
749        ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd;
750
751    // The IT bits are forced to zero when returning to A32 state, or
752    // when returning to an EL with the ITD bit set to 1, and the IT
753    // bits are describing a multi-instruction block.
754    if (itd && bits(it, 2, 0) != 0)
755        return 0;
756
757    return it;
758}
759
760static bool
761illegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
762{
763    const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode;
764    if (badMode(mode))
765        return true;
766
767    const OperatingMode cur_mode = (OperatingMode) (uint8_t)cpsr.mode;
768    const ExceptionLevel target_el = opModeToEL(mode);
769    if (target_el > opModeToEL(cur_mode))
770        return true;
771
772    if (target_el == EL3 && !ArmSystem::haveSecurity(tc))
773        return true;
774
775    if (target_el == EL2 && !ArmSystem::haveVirtualization(tc))
776        return true;
777
778    if (!spsr.width) {
779        // aarch64
780        if (!ArmSystem::highestELIs64(tc))
781            return true;
782
783        if (spsr & 0x2)
784            return true;
785        if (target_el == EL0 && spsr.sp)
786            return true;
787        if (target_el == EL2 && !((SCR)tc->readMiscReg(MISCREG_SCR_EL3)).ns)
788            return false;
789    } else {
790        return badMode32(mode);
791    }
792
793    return false;
794}
795
796CPSR
797ArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
798{
799    CPSR new_cpsr = 0;
800
801    // gem5 doesn't implement single-stepping, so force the SS bit to
802    // 0.
803    new_cpsr.ss = 0;
804
805    if (illegalExceptionReturn(tc, cpsr, spsr)) {
806        new_cpsr.il = 1;
807    } else {
808        new_cpsr.il = spsr.il;
809        if (spsr.width && badMode32((OperatingMode)(uint8_t)spsr.mode)) {
810            new_cpsr.il = 1;
811        } else if (spsr.width) {
812            new_cpsr.mode = spsr.mode;
813        } else {
814            new_cpsr.el = spsr.el;
815            new_cpsr.sp = spsr.sp;
816        }
817    }
818
819    new_cpsr.nz = spsr.nz;
820    new_cpsr.c = spsr.c;
821    new_cpsr.v = spsr.v;
822    if (new_cpsr.width) {
823        // aarch32
824        const ITSTATE it = getRestoredITBits(tc, spsr);
825        new_cpsr.q = spsr.q;
826        new_cpsr.ge = spsr.ge;
827        new_cpsr.e = spsr.e;
828        new_cpsr.aif = spsr.aif;
829        new_cpsr.t = spsr.t;
830        new_cpsr.it2 = it.top6;
831        new_cpsr.it1 = it.bottom2;
832    } else {
833        // aarch64
834        new_cpsr.daif = spsr.daif;
835    }
836
837    return new_cpsr;
838}
839
840
841
842}
843