static_inst.cc revision 12510
17094Sgblack@eecs.umich.edu/*
212497Sgiacomo.travaglini@arm.com * Copyright (c) 2010-2014, 2016-2018 ARM Limited
39913Ssteve.reinhardt@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
47094Sgblack@eecs.umich.edu * All rights reserved
57094Sgblack@eecs.umich.edu *
67094Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
77094Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
87094Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
97094Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
107094Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
117094Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
127094Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
137094Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
147094Sgblack@eecs.umich.edu *
157094Sgblack@eecs.umich.edu * Copyright (c) 2007-2008 The Florida State University
166253Sgblack@eecs.umich.edu * All rights reserved.
176253Sgblack@eecs.umich.edu *
186253Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
196253Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
206253Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
216253Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
226253Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
236253Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
246253Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
256253Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
266253Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
276253Sgblack@eecs.umich.edu * this software without specific prior written permission.
286253Sgblack@eecs.umich.edu *
296253Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
306253Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
316253Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
326253Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
336253Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
346253Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
356253Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
366253Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
376253Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
386253Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
396253Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
406253Sgblack@eecs.umich.edu *
416253Sgblack@eecs.umich.edu * Authors: Stephen Hines
426253Sgblack@eecs.umich.edu */
436253Sgblack@eecs.umich.edu
448229Snate@binkert.org#include "arch/arm/insts/static_inst.hh"
4511793Sbrandon.potter@amd.com
466759SAli.Saidi@ARM.com#include "arch/arm/faults.hh"
476255Sgblack@eecs.umich.edu#include "base/condcodes.hh"
486712Snate@binkert.org#include "base/cprintf.hh"
4911793Sbrandon.potter@amd.com#include "base/loader/symtab.hh"
509913Ssteve.reinhardt@amd.com#include "cpu/reg_class.hh"
516253Sgblack@eecs.umich.edu
526253Sgblack@eecs.umich.edunamespace ArmISA
536253Sgblack@eecs.umich.edu{
546254Sgblack@eecs.umich.edu// Shift Rm by an immediate value
556254Sgblack@eecs.umich.eduint32_t
567148Sgblack@eecs.umich.eduArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt,
577094Sgblack@eecs.umich.edu                                uint32_t type, uint32_t cfval) const
586254Sgblack@eecs.umich.edu{
596255Sgblack@eecs.umich.edu    assert(shamt < 32);
606255Sgblack@eecs.umich.edu    ArmShiftType shiftType;
616255Sgblack@eecs.umich.edu    shiftType = (ArmShiftType)type;
626254Sgblack@eecs.umich.edu
636254Sgblack@eecs.umich.edu    switch (shiftType)
646254Sgblack@eecs.umich.edu    {
656255Sgblack@eecs.umich.edu      case LSL:
666255Sgblack@eecs.umich.edu        return base << shamt;
676255Sgblack@eecs.umich.edu      case LSR:
686255Sgblack@eecs.umich.edu        if (shamt == 0)
696255Sgblack@eecs.umich.edu            return 0;
706255Sgblack@eecs.umich.edu        else
716255Sgblack@eecs.umich.edu            return base >> shamt;
726255Sgblack@eecs.umich.edu      case ASR:
736255Sgblack@eecs.umich.edu        if (shamt == 0)
747182Sgblack@eecs.umich.edu            return (base >> 31) | -((base & (1 << 31)) >> 31);
756255Sgblack@eecs.umich.edu        else
767182Sgblack@eecs.umich.edu            return (base >> shamt) | -((base & (1 << 31)) >> shamt);
776255Sgblack@eecs.umich.edu      case ROR:
786255Sgblack@eecs.umich.edu        if (shamt == 0)
796255Sgblack@eecs.umich.edu            return (cfval << 31) | (base >> 1); // RRX
806255Sgblack@eecs.umich.edu        else
816255Sgblack@eecs.umich.edu            return (base << (32 - shamt)) | (base >> shamt);
826255Sgblack@eecs.umich.edu      default:
836712Snate@binkert.org        ccprintf(std::cerr, "Unhandled shift type\n");
846255Sgblack@eecs.umich.edu        exit(1);
856255Sgblack@eecs.umich.edu        break;
866254Sgblack@eecs.umich.edu    }
876254Sgblack@eecs.umich.edu    return 0;
886254Sgblack@eecs.umich.edu}
896254Sgblack@eecs.umich.edu
9010037SARM gem5 Developersint64_t
9110037SARM gem5 DevelopersArmStaticInst::shiftReg64(uint64_t base, uint64_t shiftAmt,
9210037SARM gem5 Developers                          ArmShiftType type, uint8_t width) const
9310037SARM gem5 Developers{
9410037SARM gem5 Developers    shiftAmt = shiftAmt % width;
9510037SARM gem5 Developers    ArmShiftType shiftType;
9610037SARM gem5 Developers    shiftType = (ArmShiftType)type;
9710037SARM gem5 Developers
9810037SARM gem5 Developers    switch (shiftType)
9910037SARM gem5 Developers    {
10010037SARM gem5 Developers      case LSL:
10110037SARM gem5 Developers        return base << shiftAmt;
10210037SARM gem5 Developers      case LSR:
10310037SARM gem5 Developers        if (shiftAmt == 0)
10410037SARM gem5 Developers            return base;
10510037SARM gem5 Developers        else
10610037SARM gem5 Developers            return (base & mask(width)) >> shiftAmt;
10710037SARM gem5 Developers      case ASR:
10810037SARM gem5 Developers        if (shiftAmt == 0) {
10910037SARM gem5 Developers            return base;
11010037SARM gem5 Developers        } else {
11110037SARM gem5 Developers            int sign_bit = bits(base, intWidth - 1);
11210037SARM gem5 Developers            base >>= shiftAmt;
11310037SARM gem5 Developers            base = sign_bit ? (base | ~mask(intWidth - shiftAmt)) : base;
11410037SARM gem5 Developers            return base & mask(intWidth);
11510037SARM gem5 Developers        }
11610037SARM gem5 Developers      case ROR:
11710037SARM gem5 Developers        if (shiftAmt == 0)
11810037SARM gem5 Developers            return base;
11910037SARM gem5 Developers        else
12010037SARM gem5 Developers            return (base << (width - shiftAmt)) | (base >> shiftAmt);
12110037SARM gem5 Developers      default:
12210037SARM gem5 Developers        ccprintf(std::cerr, "Unhandled shift type\n");
12310037SARM gem5 Developers        exit(1);
12410037SARM gem5 Developers        break;
12510037SARM gem5 Developers    }
12610037SARM gem5 Developers    return 0;
12710037SARM gem5 Developers}
12810037SARM gem5 Developers
12910037SARM gem5 Developersint64_t
13010037SARM gem5 DevelopersArmStaticInst::extendReg64(uint64_t base, ArmExtendType type,
13110037SARM gem5 Developers                           uint64_t shiftAmt, uint8_t width) const
13210037SARM gem5 Developers{
13310037SARM gem5 Developers    bool sign_extend = false;
13410037SARM gem5 Developers    int len = 0;
13510037SARM gem5 Developers    switch (type) {
13610037SARM gem5 Developers      case UXTB:
13710037SARM gem5 Developers        len = 8;
13810037SARM gem5 Developers        break;
13910037SARM gem5 Developers      case UXTH:
14010037SARM gem5 Developers        len = 16;
14110037SARM gem5 Developers        break;
14210037SARM gem5 Developers      case UXTW:
14310037SARM gem5 Developers        len = 32;
14410037SARM gem5 Developers        break;
14510037SARM gem5 Developers      case UXTX:
14610037SARM gem5 Developers        len = 64;
14710037SARM gem5 Developers        break;
14810037SARM gem5 Developers      case SXTB:
14910037SARM gem5 Developers        len = 8;
15010037SARM gem5 Developers        sign_extend = true;
15110037SARM gem5 Developers        break;
15210037SARM gem5 Developers      case SXTH:
15310037SARM gem5 Developers        len = 16;
15410037SARM gem5 Developers        sign_extend = true;
15510037SARM gem5 Developers        break;
15610037SARM gem5 Developers      case SXTW:
15710037SARM gem5 Developers        len = 32;
15810037SARM gem5 Developers        sign_extend = true;
15910037SARM gem5 Developers        break;
16010037SARM gem5 Developers      case SXTX:
16110037SARM gem5 Developers        len = 64;
16210037SARM gem5 Developers        sign_extend = true;
16310037SARM gem5 Developers        break;
16410037SARM gem5 Developers    }
16510037SARM gem5 Developers    len = len <= width - shiftAmt ? len : width - shiftAmt;
16610037SARM gem5 Developers    uint64_t tmp = (uint64_t) bits(base, len - 1, 0) << shiftAmt;
16710037SARM gem5 Developers    if (sign_extend) {
16810037SARM gem5 Developers        int sign_bit = bits(tmp, len + shiftAmt - 1);
16910037SARM gem5 Developers        tmp = sign_bit ? (tmp | ~mask(len + shiftAmt)) : tmp;
17010037SARM gem5 Developers    }
17110037SARM gem5 Developers    return tmp & mask(width);
17210037SARM gem5 Developers}
17310037SARM gem5 Developers
1746254Sgblack@eecs.umich.edu// Shift Rm by Rs
1756254Sgblack@eecs.umich.eduint32_t
1767148Sgblack@eecs.umich.eduArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt,
1777094Sgblack@eecs.umich.edu                               uint32_t type, uint32_t cfval) const
1786254Sgblack@eecs.umich.edu{
1796254Sgblack@eecs.umich.edu    enum ArmShiftType shiftType;
1806254Sgblack@eecs.umich.edu    shiftType = (enum ArmShiftType) type;
1816254Sgblack@eecs.umich.edu
1826254Sgblack@eecs.umich.edu    switch (shiftType)
1836254Sgblack@eecs.umich.edu    {
1846255Sgblack@eecs.umich.edu      case LSL:
1856255Sgblack@eecs.umich.edu        if (shamt >= 32)
1866255Sgblack@eecs.umich.edu            return 0;
1876255Sgblack@eecs.umich.edu        else
1886255Sgblack@eecs.umich.edu            return base << shamt;
1896255Sgblack@eecs.umich.edu      case LSR:
1906255Sgblack@eecs.umich.edu        if (shamt >= 32)
1916255Sgblack@eecs.umich.edu            return 0;
1926255Sgblack@eecs.umich.edu        else
1936255Sgblack@eecs.umich.edu            return base >> shamt;
1946255Sgblack@eecs.umich.edu      case ASR:
1956255Sgblack@eecs.umich.edu        if (shamt >= 32)
1967182Sgblack@eecs.umich.edu            return (base >> 31) | -((base & (1 << 31)) >> 31);
1976255Sgblack@eecs.umich.edu        else
1987182Sgblack@eecs.umich.edu            return (base >> shamt) | -((base & (1 << 31)) >> shamt);
1996255Sgblack@eecs.umich.edu      case ROR:
2006255Sgblack@eecs.umich.edu        shamt = shamt & 0x1f;
2016255Sgblack@eecs.umich.edu        if (shamt == 0)
2026255Sgblack@eecs.umich.edu            return base;
2036255Sgblack@eecs.umich.edu        else
2046255Sgblack@eecs.umich.edu            return (base << (32 - shamt)) | (base >> shamt);
2056255Sgblack@eecs.umich.edu      default:
2066712Snate@binkert.org        ccprintf(std::cerr, "Unhandled shift type\n");
2076255Sgblack@eecs.umich.edu        exit(1);
2086255Sgblack@eecs.umich.edu        break;
2096254Sgblack@eecs.umich.edu    }
2106254Sgblack@eecs.umich.edu    return 0;
2116254Sgblack@eecs.umich.edu}
2126254Sgblack@eecs.umich.edu
2136254Sgblack@eecs.umich.edu
2146254Sgblack@eecs.umich.edu// Generate C for a shift by immediate
2156255Sgblack@eecs.umich.edubool
2167148Sgblack@eecs.umich.eduArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt,
2177094Sgblack@eecs.umich.edu                                   uint32_t type, uint32_t cfval) const
2186254Sgblack@eecs.umich.edu{
2196254Sgblack@eecs.umich.edu    enum ArmShiftType shiftType;
2206254Sgblack@eecs.umich.edu    shiftType = (enum ArmShiftType) type;
2216254Sgblack@eecs.umich.edu
2226254Sgblack@eecs.umich.edu    switch (shiftType)
2236254Sgblack@eecs.umich.edu    {
2246255Sgblack@eecs.umich.edu      case LSL:
2256255Sgblack@eecs.umich.edu        if (shamt == 0)
2266255Sgblack@eecs.umich.edu            return cfval;
2276255Sgblack@eecs.umich.edu        else
2286254Sgblack@eecs.umich.edu            return (base >> (32 - shamt)) & 1;
2296255Sgblack@eecs.umich.edu      case LSR:
2306255Sgblack@eecs.umich.edu        if (shamt == 0)
2316255Sgblack@eecs.umich.edu            return (base >> 31);
2326255Sgblack@eecs.umich.edu        else
2336255Sgblack@eecs.umich.edu            return (base >> (shamt - 1)) & 1;
2346255Sgblack@eecs.umich.edu      case ASR:
2356255Sgblack@eecs.umich.edu        if (shamt == 0)
2366255Sgblack@eecs.umich.edu            return (base >> 31);
2376255Sgblack@eecs.umich.edu        else
2386255Sgblack@eecs.umich.edu            return (base >> (shamt - 1)) & 1;
2396255Sgblack@eecs.umich.edu      case ROR:
2406255Sgblack@eecs.umich.edu        shamt = shamt & 0x1f;
2416255Sgblack@eecs.umich.edu        if (shamt == 0)
2426255Sgblack@eecs.umich.edu            return (base & 1); // RRX
2436255Sgblack@eecs.umich.edu        else
2446255Sgblack@eecs.umich.edu            return (base >> (shamt - 1)) & 1;
2456255Sgblack@eecs.umich.edu      default:
2466712Snate@binkert.org        ccprintf(std::cerr, "Unhandled shift type\n");
2476255Sgblack@eecs.umich.edu        exit(1);
2486255Sgblack@eecs.umich.edu        break;
2496254Sgblack@eecs.umich.edu    }
2506254Sgblack@eecs.umich.edu    return 0;
2516254Sgblack@eecs.umich.edu}
2526254Sgblack@eecs.umich.edu
2536254Sgblack@eecs.umich.edu
2546254Sgblack@eecs.umich.edu// Generate C for a shift by Rs
2556255Sgblack@eecs.umich.edubool
2567148Sgblack@eecs.umich.eduArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
2577094Sgblack@eecs.umich.edu                                  uint32_t type, uint32_t cfval) const
2586254Sgblack@eecs.umich.edu{
2596254Sgblack@eecs.umich.edu    enum ArmShiftType shiftType;
2606254Sgblack@eecs.umich.edu    shiftType = (enum ArmShiftType) type;
2616254Sgblack@eecs.umich.edu
2626255Sgblack@eecs.umich.edu    if (shamt == 0)
2636255Sgblack@eecs.umich.edu        return cfval;
2646255Sgblack@eecs.umich.edu
2656254Sgblack@eecs.umich.edu    switch (shiftType)
2666254Sgblack@eecs.umich.edu    {
2676255Sgblack@eecs.umich.edu      case LSL:
2686255Sgblack@eecs.umich.edu        if (shamt > 32)
2696255Sgblack@eecs.umich.edu            return 0;
2706255Sgblack@eecs.umich.edu        else
2716255Sgblack@eecs.umich.edu            return (base >> (32 - shamt)) & 1;
2726255Sgblack@eecs.umich.edu      case LSR:
2736255Sgblack@eecs.umich.edu        if (shamt > 32)
2746255Sgblack@eecs.umich.edu            return 0;
2756255Sgblack@eecs.umich.edu        else
2766255Sgblack@eecs.umich.edu            return (base >> (shamt - 1)) & 1;
2776255Sgblack@eecs.umich.edu      case ASR:
2786255Sgblack@eecs.umich.edu        if (shamt > 32)
2796255Sgblack@eecs.umich.edu            shamt = 32;
2806255Sgblack@eecs.umich.edu        return (base >> (shamt - 1)) & 1;
2816255Sgblack@eecs.umich.edu      case ROR:
2826255Sgblack@eecs.umich.edu        shamt = shamt & 0x1f;
2836255Sgblack@eecs.umich.edu        if (shamt == 0)
2846255Sgblack@eecs.umich.edu            shamt = 32;
2856255Sgblack@eecs.umich.edu        return (base >> (shamt - 1)) & 1;
2866255Sgblack@eecs.umich.edu      default:
2876712Snate@binkert.org        ccprintf(std::cerr, "Unhandled shift type\n");
2886255Sgblack@eecs.umich.edu        exit(1);
2896255Sgblack@eecs.umich.edu        break;
2906254Sgblack@eecs.umich.edu    }
2916254Sgblack@eecs.umich.edu    return 0;
2926254Sgblack@eecs.umich.edu}
2936254Sgblack@eecs.umich.edu
29412104Snathanael.premillieu@arm.comvoid
29512104Snathanael.premillieu@arm.comArmStaticInst::printIntReg(std::ostream &os, RegIndex reg_idx) const
29612104Snathanael.premillieu@arm.com{
29712104Snathanael.premillieu@arm.com    if (aarch64) {
29812104Snathanael.premillieu@arm.com        if (reg_idx == INTREG_UREG0)
29912104Snathanael.premillieu@arm.com            ccprintf(os, "ureg0");
30012104Snathanael.premillieu@arm.com        else if (reg_idx == INTREG_SPX)
30112104Snathanael.premillieu@arm.com            ccprintf(os, "%s%s", (intWidth == 32) ? "w" : "", "sp");
30212104Snathanael.premillieu@arm.com        else if (reg_idx == INTREG_X31)
30312104Snathanael.premillieu@arm.com            ccprintf(os, "%szr", (intWidth == 32) ? "w" : "x");
30412104Snathanael.premillieu@arm.com        else
30512104Snathanael.premillieu@arm.com            ccprintf(os, "%s%d", (intWidth == 32) ? "w" : "x", reg_idx);
30612104Snathanael.premillieu@arm.com    } else {
30712104Snathanael.premillieu@arm.com        switch (reg_idx) {
30812104Snathanael.premillieu@arm.com          case PCReg:
30912104Snathanael.premillieu@arm.com            ccprintf(os, "pc");
31012104Snathanael.premillieu@arm.com            break;
31112104Snathanael.premillieu@arm.com          case StackPointerReg:
31212104Snathanael.premillieu@arm.com            ccprintf(os, "sp");
31312104Snathanael.premillieu@arm.com            break;
31412104Snathanael.premillieu@arm.com          case FramePointerReg:
31512104Snathanael.premillieu@arm.com             ccprintf(os, "fp");
31612104Snathanael.premillieu@arm.com             break;
31712104Snathanael.premillieu@arm.com          case ReturnAddressReg:
31812104Snathanael.premillieu@arm.com             ccprintf(os, "lr");
31912104Snathanael.premillieu@arm.com             break;
32012104Snathanael.premillieu@arm.com          default:
32112104Snathanael.premillieu@arm.com             ccprintf(os, "r%d", reg_idx);
32212104Snathanael.premillieu@arm.com             break;
32312104Snathanael.premillieu@arm.com        }
32412104Snathanael.premillieu@arm.com    }
32512104Snathanael.premillieu@arm.com}
3266254Sgblack@eecs.umich.edu
3276254Sgblack@eecs.umich.eduvoid
32812104Snathanael.premillieu@arm.comArmStaticInst::printFloatReg(std::ostream &os, RegIndex reg_idx) const
3296253Sgblack@eecs.umich.edu{
33012104Snathanael.premillieu@arm.com    ccprintf(os, "f%d", reg_idx);
33112104Snathanael.premillieu@arm.com}
3329913Ssteve.reinhardt@amd.com
33312104Snathanael.premillieu@arm.comvoid
33412109SRekai.GonzalezAlberquilla@arm.comArmStaticInst::printVecReg(std::ostream &os, RegIndex reg_idx) const
33512109SRekai.GonzalezAlberquilla@arm.com{
33612109SRekai.GonzalezAlberquilla@arm.com    ccprintf(os, "v%d", reg_idx);
33712109SRekai.GonzalezAlberquilla@arm.com}
33812109SRekai.GonzalezAlberquilla@arm.com
33912109SRekai.GonzalezAlberquilla@arm.comvoid
34012104Snathanael.premillieu@arm.comArmStaticInst::printCCReg(std::ostream &os, RegIndex reg_idx) const
34112104Snathanael.premillieu@arm.com{
34212104Snathanael.premillieu@arm.com    ccprintf(os, "cc_%s", ArmISA::ccRegName[reg_idx]);
34312104Snathanael.premillieu@arm.com}
34412104Snathanael.premillieu@arm.com
34512104Snathanael.premillieu@arm.comvoid
34612104Snathanael.premillieu@arm.comArmStaticInst::printMiscReg(std::ostream &os, RegIndex reg_idx) const
34712104Snathanael.premillieu@arm.com{
34812104Snathanael.premillieu@arm.com    assert(reg_idx < NUM_MISCREGS);
34912104Snathanael.premillieu@arm.com    ccprintf(os, "%s", ArmISA::miscRegName[reg_idx]);
3506253Sgblack@eecs.umich.edu}
3516253Sgblack@eecs.umich.edu
3526262Sgblack@eecs.umich.eduvoid
3537148Sgblack@eecs.umich.eduArmStaticInst::printMnemonic(std::ostream &os,
3546262Sgblack@eecs.umich.edu                             const std::string &suffix,
35510037SARM gem5 Developers                             bool withPred,
35610037SARM gem5 Developers                             bool withCond64,
35710037SARM gem5 Developers                             ConditionCode cond64) const
3586262Sgblack@eecs.umich.edu{
3596262Sgblack@eecs.umich.edu    os << "  " << mnemonic;
36010037SARM gem5 Developers    if (withPred && !aarch64) {
36110037SARM gem5 Developers        printCondition(os, machInst.condCode);
3627122Sgblack@eecs.umich.edu        os << suffix;
36310037SARM gem5 Developers    } else if (withCond64) {
36410037SARM gem5 Developers        os << ".";
36510037SARM gem5 Developers        printCondition(os, cond64);
36610037SARM gem5 Developers        os << suffix;
36710037SARM gem5 Developers    }
36810037SARM gem5 Developers    if (machInst.bigThumb)
36910037SARM gem5 Developers        os << ".w";
37010037SARM gem5 Developers    os << "   ";
37110037SARM gem5 Developers}
37210037SARM gem5 Developers
37310037SARM gem5 Developersvoid
37410037SARM gem5 DevelopersArmStaticInst::printTarget(std::ostream &os, Addr target,
37510037SARM gem5 Developers                           const SymbolTable *symtab) const
37610037SARM gem5 Developers{
37710037SARM gem5 Developers    Addr symbolAddr;
37810037SARM gem5 Developers    std::string symbol;
37910037SARM gem5 Developers
38010037SARM gem5 Developers    if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) {
38110037SARM gem5 Developers        ccprintf(os, "<%s", symbol);
38210037SARM gem5 Developers        if (symbolAddr != target)
38310037SARM gem5 Developers            ccprintf(os, "+%d>", target - symbolAddr);
38410037SARM gem5 Developers        else
38510037SARM gem5 Developers            ccprintf(os, ">");
38610037SARM gem5 Developers    } else {
38710037SARM gem5 Developers        ccprintf(os, "%#x", target);
38810037SARM gem5 Developers    }
38910037SARM gem5 Developers}
39010037SARM gem5 Developers
39110037SARM gem5 Developersvoid
39210037SARM gem5 DevelopersArmStaticInst::printCondition(std::ostream &os,
39310037SARM gem5 Developers                              unsigned code,
39410037SARM gem5 Developers                              bool noImplicit) const
39510037SARM gem5 Developers{
39610037SARM gem5 Developers    switch (code) {
39710037SARM gem5 Developers      case COND_EQ:
39810037SARM gem5 Developers        os << "eq";
39910037SARM gem5 Developers        break;
40010037SARM gem5 Developers      case COND_NE:
40110037SARM gem5 Developers        os << "ne";
40210037SARM gem5 Developers        break;
40310037SARM gem5 Developers      case COND_CS:
40410037SARM gem5 Developers        os << "cs";
40510037SARM gem5 Developers        break;
40610037SARM gem5 Developers      case COND_CC:
40710037SARM gem5 Developers        os << "cc";
40810037SARM gem5 Developers        break;
40910037SARM gem5 Developers      case COND_MI:
41010037SARM gem5 Developers        os << "mi";
41110037SARM gem5 Developers        break;
41210037SARM gem5 Developers      case COND_PL:
41310037SARM gem5 Developers        os << "pl";
41410037SARM gem5 Developers        break;
41510037SARM gem5 Developers      case COND_VS:
41610037SARM gem5 Developers        os << "vs";
41710037SARM gem5 Developers        break;
41810037SARM gem5 Developers      case COND_VC:
41910037SARM gem5 Developers        os << "vc";
42010037SARM gem5 Developers        break;
42110037SARM gem5 Developers      case COND_HI:
42210037SARM gem5 Developers        os << "hi";
42310037SARM gem5 Developers        break;
42410037SARM gem5 Developers      case COND_LS:
42510037SARM gem5 Developers        os << "ls";
42610037SARM gem5 Developers        break;
42710037SARM gem5 Developers      case COND_GE:
42810037SARM gem5 Developers        os << "ge";
42910037SARM gem5 Developers        break;
43010037SARM gem5 Developers      case COND_LT:
43110037SARM gem5 Developers        os << "lt";
43210037SARM gem5 Developers        break;
43310037SARM gem5 Developers      case COND_GT:
43410037SARM gem5 Developers        os << "gt";
43510037SARM gem5 Developers        break;
43610037SARM gem5 Developers      case COND_LE:
43710037SARM gem5 Developers        os << "le";
43810037SARM gem5 Developers        break;
43910037SARM gem5 Developers      case COND_AL:
44010037SARM gem5 Developers        // This one is implicit.
44110037SARM gem5 Developers        if (noImplicit)
44210037SARM gem5 Developers            os << "al";
44310037SARM gem5 Developers        break;
44410037SARM gem5 Developers      case COND_UC:
44510037SARM gem5 Developers        // Unconditional.
44610037SARM gem5 Developers        if (noImplicit)
44710037SARM gem5 Developers            os << "uc";
44810037SARM gem5 Developers        break;
44910037SARM gem5 Developers      default:
45010037SARM gem5 Developers        panic("Unrecognized condition code %d.\n", code);
4516262Sgblack@eecs.umich.edu    }
4526262Sgblack@eecs.umich.edu}
4536262Sgblack@eecs.umich.edu
4546263Sgblack@eecs.umich.eduvoid
4557148Sgblack@eecs.umich.eduArmStaticInst::printMemSymbol(std::ostream &os,
4566263Sgblack@eecs.umich.edu                              const SymbolTable *symtab,
4576263Sgblack@eecs.umich.edu                              const std::string &prefix,
4586263Sgblack@eecs.umich.edu                              const Addr addr,
4596263Sgblack@eecs.umich.edu                              const std::string &suffix) const
4606263Sgblack@eecs.umich.edu{
4616263Sgblack@eecs.umich.edu    Addr symbolAddr;
4626263Sgblack@eecs.umich.edu    std::string symbol;
4636263Sgblack@eecs.umich.edu    if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
4646263Sgblack@eecs.umich.edu        ccprintf(os, "%s%s", prefix, symbol);
4656263Sgblack@eecs.umich.edu        if (symbolAddr != addr)
4666263Sgblack@eecs.umich.edu            ccprintf(os, "+%d", addr - symbolAddr);
4676263Sgblack@eecs.umich.edu        ccprintf(os, suffix);
4686263Sgblack@eecs.umich.edu    }
4696263Sgblack@eecs.umich.edu}
4706263Sgblack@eecs.umich.edu
4716264Sgblack@eecs.umich.eduvoid
4727148Sgblack@eecs.umich.eduArmStaticInst::printShiftOperand(std::ostream &os,
4737142Sgblack@eecs.umich.edu                                     IntRegIndex rm,
4747142Sgblack@eecs.umich.edu                                     bool immShift,
4757142Sgblack@eecs.umich.edu                                     uint32_t shiftAmt,
4767142Sgblack@eecs.umich.edu                                     IntRegIndex rs,
4777142Sgblack@eecs.umich.edu                                     ArmShiftType type) const
4786264Sgblack@eecs.umich.edu{
4797142Sgblack@eecs.umich.edu    bool firstOp = false;
4806264Sgblack@eecs.umich.edu
4817142Sgblack@eecs.umich.edu    if (rm != INTREG_ZERO) {
48212104Snathanael.premillieu@arm.com        printIntReg(os, rm);
4837142Sgblack@eecs.umich.edu    }
4847142Sgblack@eecs.umich.edu
4856306Sgblack@eecs.umich.edu    bool done = false;
4866264Sgblack@eecs.umich.edu
4876306Sgblack@eecs.umich.edu    if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
4886306Sgblack@eecs.umich.edu        shiftAmt = 32;
4896264Sgblack@eecs.umich.edu
4906306Sgblack@eecs.umich.edu    switch (type) {
4916306Sgblack@eecs.umich.edu      case LSL:
4926306Sgblack@eecs.umich.edu        if (immShift && shiftAmt == 0) {
4936306Sgblack@eecs.umich.edu            done = true;
4946264Sgblack@eecs.umich.edu            break;
4956306Sgblack@eecs.umich.edu        }
4967142Sgblack@eecs.umich.edu        if (!firstOp)
4977142Sgblack@eecs.umich.edu            os << ", ";
4987142Sgblack@eecs.umich.edu        os << "LSL";
4996306Sgblack@eecs.umich.edu        break;
5006306Sgblack@eecs.umich.edu      case LSR:
5017142Sgblack@eecs.umich.edu        if (!firstOp)
5027142Sgblack@eecs.umich.edu            os << ", ";
5037142Sgblack@eecs.umich.edu        os << "LSR";
5046306Sgblack@eecs.umich.edu        break;
5056306Sgblack@eecs.umich.edu      case ASR:
5067142Sgblack@eecs.umich.edu        if (!firstOp)
5077142Sgblack@eecs.umich.edu            os << ", ";
5087142Sgblack@eecs.umich.edu        os << "ASR";
5096306Sgblack@eecs.umich.edu        break;
5106306Sgblack@eecs.umich.edu      case ROR:
5116306Sgblack@eecs.umich.edu        if (immShift && shiftAmt == 0) {
5127142Sgblack@eecs.umich.edu            if (!firstOp)
5137142Sgblack@eecs.umich.edu                os << ", ";
5147142Sgblack@eecs.umich.edu            os << "RRX";
5156306Sgblack@eecs.umich.edu            done = true;
5166264Sgblack@eecs.umich.edu            break;
5176264Sgblack@eecs.umich.edu        }
5187142Sgblack@eecs.umich.edu        if (!firstOp)
5197142Sgblack@eecs.umich.edu            os << ", ";
5207142Sgblack@eecs.umich.edu        os << "ROR";
5216306Sgblack@eecs.umich.edu        break;
5226306Sgblack@eecs.umich.edu      default:
5236306Sgblack@eecs.umich.edu        panic("Tried to disassemble unrecognized shift type.\n");
5246306Sgblack@eecs.umich.edu    }
5256306Sgblack@eecs.umich.edu    if (!done) {
5267142Sgblack@eecs.umich.edu        if (!firstOp)
5277142Sgblack@eecs.umich.edu            os << " ";
5286306Sgblack@eecs.umich.edu        if (immShift)
5296306Sgblack@eecs.umich.edu            os << "#" << shiftAmt;
5306306Sgblack@eecs.umich.edu        else
53112104Snathanael.premillieu@arm.com            printIntReg(os, rs);
5326264Sgblack@eecs.umich.edu    }
5336264Sgblack@eecs.umich.edu}
5346264Sgblack@eecs.umich.edu
5356264Sgblack@eecs.umich.eduvoid
53610037SARM gem5 DevelopersArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os,
53710037SARM gem5 Developers                                  IntRegIndex rm, ArmExtendType type,
53810037SARM gem5 Developers                                  int64_t shiftAmt) const
53910037SARM gem5 Developers{
54010037SARM gem5 Developers    if (!firstOperand)
54110037SARM gem5 Developers        ccprintf(os, ", ");
54212104Snathanael.premillieu@arm.com    printIntReg(os, rm);
54310037SARM gem5 Developers    if (type == UXTX && shiftAmt == 0)
54410037SARM gem5 Developers        return;
54510037SARM gem5 Developers    switch (type) {
54610037SARM gem5 Developers      case UXTB: ccprintf(os, ", UXTB");
54710037SARM gem5 Developers        break;
54810037SARM gem5 Developers      case UXTH: ccprintf(os, ", UXTH");
54910037SARM gem5 Developers        break;
55010037SARM gem5 Developers      case UXTW: ccprintf(os, ", UXTW");
55110037SARM gem5 Developers        break;
55210037SARM gem5 Developers      case UXTX: ccprintf(os, ", LSL");
55310037SARM gem5 Developers        break;
55410037SARM gem5 Developers      case SXTB: ccprintf(os, ", SXTB");
55510037SARM gem5 Developers        break;
55610037SARM gem5 Developers      case SXTH: ccprintf(os, ", SXTH");
55710037SARM gem5 Developers        break;
55810037SARM gem5 Developers      case SXTW: ccprintf(os, ", SXTW");
55910037SARM gem5 Developers        break;
56010037SARM gem5 Developers      case SXTX: ccprintf(os, ", SXTW");
56110037SARM gem5 Developers        break;
56210037SARM gem5 Developers    }
56310037SARM gem5 Developers    if (type == UXTX || shiftAmt)
56410037SARM gem5 Developers        ccprintf(os, " #%d", shiftAmt);
56510037SARM gem5 Developers}
56610037SARM gem5 Developers
56710037SARM gem5 Developersvoid
5687148Sgblack@eecs.umich.eduArmStaticInst::printDataInst(std::ostream &os, bool withImm,
5697142Sgblack@eecs.umich.edu        bool immShift, bool s, IntRegIndex rd, IntRegIndex rn,
5707142Sgblack@eecs.umich.edu        IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt,
57111371Snathanael.premillieu@arm.com        ArmShiftType type, uint64_t imm) const
5726264Sgblack@eecs.umich.edu{
5737142Sgblack@eecs.umich.edu    printMnemonic(os, s ? "s" : "");
5746264Sgblack@eecs.umich.edu    bool firstOp = true;
5756264Sgblack@eecs.umich.edu
5766264Sgblack@eecs.umich.edu    // Destination
5777142Sgblack@eecs.umich.edu    if (rd != INTREG_ZERO) {
5786264Sgblack@eecs.umich.edu        firstOp = false;
57912104Snathanael.premillieu@arm.com        printIntReg(os, rd);
5806264Sgblack@eecs.umich.edu    }
5816264Sgblack@eecs.umich.edu
5826264Sgblack@eecs.umich.edu    // Source 1.
5837142Sgblack@eecs.umich.edu    if (rn != INTREG_ZERO) {
5846264Sgblack@eecs.umich.edu        if (!firstOp)
5856264Sgblack@eecs.umich.edu            os << ", ";
5866264Sgblack@eecs.umich.edu        firstOp = false;
58712104Snathanael.premillieu@arm.com        printIntReg(os, rn);
5886264Sgblack@eecs.umich.edu    }
5896264Sgblack@eecs.umich.edu
5906264Sgblack@eecs.umich.edu    if (!firstOp)
5916264Sgblack@eecs.umich.edu        os << ", ";
5926306Sgblack@eecs.umich.edu    if (withImm) {
59311371Snathanael.premillieu@arm.com        ccprintf(os, "#%ld", imm);
5946306Sgblack@eecs.umich.edu    } else {
5957142Sgblack@eecs.umich.edu        printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
5966306Sgblack@eecs.umich.edu    }
5976264Sgblack@eecs.umich.edu}
5986264Sgblack@eecs.umich.edu
5996254Sgblack@eecs.umich.edustd::string
6007148Sgblack@eecs.umich.eduArmStaticInst::generateDisassembly(Addr pc,
6016254Sgblack@eecs.umich.edu                                   const SymbolTable *symtab) const
6026253Sgblack@eecs.umich.edu{
6036253Sgblack@eecs.umich.edu    std::stringstream ss;
6046262Sgblack@eecs.umich.edu    printMnemonic(ss);
6056253Sgblack@eecs.umich.edu    return ss.str();
6066253Sgblack@eecs.umich.edu}
60711513Sandreas.sandberg@arm.com
60811513Sandreas.sandberg@arm.com
60911513Sandreas.sandberg@arm.comFault
61011513Sandreas.sandberg@arm.comArmStaticInst::advSIMDFPAccessTrap64(ExceptionLevel el) const
61111513Sandreas.sandberg@arm.com{
61211513Sandreas.sandberg@arm.com    switch (el) {
61311513Sandreas.sandberg@arm.com      case EL1:
61411513Sandreas.sandberg@arm.com        return std::make_shared<SupervisorTrap>(machInst, 0x1E00000,
61511513Sandreas.sandberg@arm.com                                                EC_TRAPPED_SIMD_FP);
61611513Sandreas.sandberg@arm.com      case EL2:
61711513Sandreas.sandberg@arm.com        return std::make_shared<HypervisorTrap>(machInst, 0x1E00000,
61811513Sandreas.sandberg@arm.com                                                EC_TRAPPED_SIMD_FP);
61911513Sandreas.sandberg@arm.com      case EL3:
62011513Sandreas.sandberg@arm.com        return std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000,
62111513Sandreas.sandberg@arm.com                                                   EC_TRAPPED_SIMD_FP);
62211513Sandreas.sandberg@arm.com
62311513Sandreas.sandberg@arm.com      default:
62411513Sandreas.sandberg@arm.com        panic("Illegal EL in advSIMDFPAccessTrap64\n");
62511513Sandreas.sandberg@arm.com    }
6266253Sgblack@eecs.umich.edu}
62711513Sandreas.sandberg@arm.com
62811513Sandreas.sandberg@arm.com
62911513Sandreas.sandberg@arm.comFault
63011513Sandreas.sandberg@arm.comArmStaticInst::checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const
63111513Sandreas.sandberg@arm.com{
63211513Sandreas.sandberg@arm.com    const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el;
63311513Sandreas.sandberg@arm.com
63411513Sandreas.sandberg@arm.com    if (ArmSystem::haveVirtualization(tc) && el <= EL2) {
63511513Sandreas.sandberg@arm.com        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL2);
63611513Sandreas.sandberg@arm.com        if (cptrEnCheck.tfp)
63711513Sandreas.sandberg@arm.com            return advSIMDFPAccessTrap64(EL2);
63811513Sandreas.sandberg@arm.com    }
63911513Sandreas.sandberg@arm.com
64011513Sandreas.sandberg@arm.com    if (ArmSystem::haveSecurity(tc)) {
64111513Sandreas.sandberg@arm.com        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3);
64211513Sandreas.sandberg@arm.com        if (cptrEnCheck.tfp)
64311513Sandreas.sandberg@arm.com            return advSIMDFPAccessTrap64(EL3);
64411513Sandreas.sandberg@arm.com    }
64511513Sandreas.sandberg@arm.com
64611513Sandreas.sandberg@arm.com    return NoFault;
64711513Sandreas.sandberg@arm.com}
64811513Sandreas.sandberg@arm.com
64911513Sandreas.sandberg@arm.comFault
65011513Sandreas.sandberg@arm.comArmStaticInst::checkFPAdvSIMDEnabled64(ThreadContext *tc,
65111513Sandreas.sandberg@arm.com                                       CPSR cpsr, CPACR cpacr) const
65211513Sandreas.sandberg@arm.com{
65311513Sandreas.sandberg@arm.com    const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el;
65411513Sandreas.sandberg@arm.com    if ((el == EL0 && cpacr.fpen != 0x3) ||
65511513Sandreas.sandberg@arm.com        (el == EL1 && !(cpacr.fpen & 0x1)))
65611513Sandreas.sandberg@arm.com        return advSIMDFPAccessTrap64(EL1);
65711513Sandreas.sandberg@arm.com
65811513Sandreas.sandberg@arm.com    return checkFPAdvSIMDTrap64(tc, cpsr);
65911513Sandreas.sandberg@arm.com}
66011513Sandreas.sandberg@arm.com
66111513Sandreas.sandberg@arm.comFault
66211513Sandreas.sandberg@arm.comArmStaticInst::checkAdvSIMDOrFPEnabled32(ThreadContext *tc,
66311513Sandreas.sandberg@arm.com                                         CPSR cpsr, CPACR cpacr,
66411513Sandreas.sandberg@arm.com                                         NSACR nsacr, FPEXC fpexc,
66511513Sandreas.sandberg@arm.com                                         bool fpexc_check, bool advsimd) const
66611513Sandreas.sandberg@arm.com{
66711513Sandreas.sandberg@arm.com    const bool have_virtualization = ArmSystem::haveVirtualization(tc);
66811513Sandreas.sandberg@arm.com    const bool have_security = ArmSystem::haveSecurity(tc);
66911513Sandreas.sandberg@arm.com    const bool is_secure = inSecureState(tc);
67011513Sandreas.sandberg@arm.com    const ExceptionLevel cur_el = opModeToEL(currOpMode(tc));
67111513Sandreas.sandberg@arm.com
67211513Sandreas.sandberg@arm.com    if (cur_el == EL0 && ELIs64(tc, EL1))
67311513Sandreas.sandberg@arm.com        return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr);
67411513Sandreas.sandberg@arm.com
67511513Sandreas.sandberg@arm.com    uint8_t cpacr_cp10 = cpacr.cp10;
67611513Sandreas.sandberg@arm.com    bool cpacr_asedis = cpacr.asedis;
67711513Sandreas.sandberg@arm.com
67811513Sandreas.sandberg@arm.com    if (have_security && !ELIs64(tc, EL3) && !is_secure) {
67911513Sandreas.sandberg@arm.com        if (nsacr.nsasedis)
68011513Sandreas.sandberg@arm.com            cpacr_asedis = true;
68111513Sandreas.sandberg@arm.com        if (nsacr.cp10 == 0)
68211513Sandreas.sandberg@arm.com            cpacr_cp10 = 0;
68311513Sandreas.sandberg@arm.com    }
68411513Sandreas.sandberg@arm.com
68511513Sandreas.sandberg@arm.com    if (cur_el != EL2) {
68611513Sandreas.sandberg@arm.com        if (advsimd && cpacr_asedis)
68711513Sandreas.sandberg@arm.com            return disabledFault();
68811513Sandreas.sandberg@arm.com
68911513Sandreas.sandberg@arm.com        if ((cur_el == EL0 && cpacr_cp10 != 0x3) ||
69011513Sandreas.sandberg@arm.com            (cur_el != EL0 && !(cpacr_cp10 & 0x1)))
69111513Sandreas.sandberg@arm.com            return disabledFault();
69211513Sandreas.sandberg@arm.com    }
69311513Sandreas.sandberg@arm.com
69411513Sandreas.sandberg@arm.com    if (fpexc_check && !fpexc.en)
69511513Sandreas.sandberg@arm.com        return disabledFault();
69611513Sandreas.sandberg@arm.com
69711513Sandreas.sandberg@arm.com    // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap --
69811513Sandreas.sandberg@arm.com
69911513Sandreas.sandberg@arm.com    if (have_virtualization && !is_secure && ELIs64(tc, EL2))
70011513Sandreas.sandberg@arm.com        return checkFPAdvSIMDTrap64(tc, cpsr);
70111513Sandreas.sandberg@arm.com
70211513Sandreas.sandberg@arm.com    if (have_virtualization && !is_secure) {
70311513Sandreas.sandberg@arm.com        HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR);
70411513Sandreas.sandberg@arm.com        bool hcptr_cp10 = hcptr.tcp10;
70511513Sandreas.sandberg@arm.com        bool hcptr_tase = hcptr.tase;
70611513Sandreas.sandberg@arm.com
70711513Sandreas.sandberg@arm.com        if (have_security && !ELIs64(tc, EL3) && !is_secure) {
70811513Sandreas.sandberg@arm.com            if (nsacr.nsasedis)
70911513Sandreas.sandberg@arm.com                hcptr_tase = true;
71011513Sandreas.sandberg@arm.com            if (nsacr.cp10)
71111513Sandreas.sandberg@arm.com                hcptr_cp10 = true;
71211513Sandreas.sandberg@arm.com        }
71311513Sandreas.sandberg@arm.com
71411513Sandreas.sandberg@arm.com        if ((advsimd && hcptr_tase) || hcptr_cp10) {
71511513Sandreas.sandberg@arm.com            const uint32_t iss = advsimd ? (1 << 5) : 0xA;
71611513Sandreas.sandberg@arm.com            if (cur_el == EL2) {
71711513Sandreas.sandberg@arm.com                return std::make_shared<UndefinedInstruction>(
71811513Sandreas.sandberg@arm.com                    machInst, iss,
71911513Sandreas.sandberg@arm.com                    EC_TRAPPED_HCPTR, mnemonic);
72011513Sandreas.sandberg@arm.com            } else {
72111513Sandreas.sandberg@arm.com                return std::make_shared<HypervisorTrap>(
72211513Sandreas.sandberg@arm.com                    machInst, iss,
72311513Sandreas.sandberg@arm.com                    EC_TRAPPED_HCPTR);
72411513Sandreas.sandberg@arm.com            }
72511513Sandreas.sandberg@arm.com
72611513Sandreas.sandberg@arm.com        }
72711513Sandreas.sandberg@arm.com    }
72811513Sandreas.sandberg@arm.com
72911513Sandreas.sandberg@arm.com    if (have_security && ELIs64(tc, EL3)) {
73011513Sandreas.sandberg@arm.com        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3);
73111513Sandreas.sandberg@arm.com        if (cptrEnCheck.tfp)
73211513Sandreas.sandberg@arm.com            return advSIMDFPAccessTrap64(EL3);
73311513Sandreas.sandberg@arm.com    }
73411513Sandreas.sandberg@arm.com
73511513Sandreas.sandberg@arm.com    return NoFault;
73611513Sandreas.sandberg@arm.com}
73711513Sandreas.sandberg@arm.com
73812403Sgiacomo.travaglini@arm.cominline bool
73912403Sgiacomo.travaglini@arm.comArmStaticInst::isWFxTrapping(ThreadContext *tc,
74012403Sgiacomo.travaglini@arm.com                             ExceptionLevel tgtEl,
74112403Sgiacomo.travaglini@arm.com                             bool isWfe) const
74212403Sgiacomo.travaglini@arm.com{
74312403Sgiacomo.travaglini@arm.com    bool trap = false;
74412403Sgiacomo.travaglini@arm.com    SCTLR sctlr = ((SCTLR)tc->readMiscReg(MISCREG_SCTLR_EL1));
74512403Sgiacomo.travaglini@arm.com    HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
74612403Sgiacomo.travaglini@arm.com    SCR scr = ((SCR)tc->readMiscReg(MISCREG_SCR_EL3));
74712403Sgiacomo.travaglini@arm.com
74812403Sgiacomo.travaglini@arm.com    switch (tgtEl) {
74912403Sgiacomo.travaglini@arm.com      case EL1:
75012403Sgiacomo.travaglini@arm.com        trap = isWfe? !sctlr.ntwe : !sctlr.ntwi;
75112403Sgiacomo.travaglini@arm.com        break;
75212403Sgiacomo.travaglini@arm.com      case EL2:
75312403Sgiacomo.travaglini@arm.com        trap = isWfe? hcr.twe : hcr.twi;
75412403Sgiacomo.travaglini@arm.com        break;
75512403Sgiacomo.travaglini@arm.com      case EL3:
75612403Sgiacomo.travaglini@arm.com        trap = isWfe? scr.twe : scr.twi;
75712403Sgiacomo.travaglini@arm.com        break;
75812403Sgiacomo.travaglini@arm.com      default:
75912403Sgiacomo.travaglini@arm.com        break;
76012403Sgiacomo.travaglini@arm.com    }
76112403Sgiacomo.travaglini@arm.com
76212403Sgiacomo.travaglini@arm.com    return trap;
76312403Sgiacomo.travaglini@arm.com}
76412403Sgiacomo.travaglini@arm.com
76512403Sgiacomo.travaglini@arm.comFault
76612403Sgiacomo.travaglini@arm.comArmStaticInst::checkForWFxTrap32(ThreadContext *tc,
76712403Sgiacomo.travaglini@arm.com                                 ExceptionLevel targetEL,
76812403Sgiacomo.travaglini@arm.com                                 bool isWfe) const
76912403Sgiacomo.travaglini@arm.com{
77012403Sgiacomo.travaglini@arm.com    // Check if target exception level is implemented.
77112403Sgiacomo.travaglini@arm.com    assert(ArmSystem::haveEL(tc, targetEL));
77212403Sgiacomo.travaglini@arm.com
77312403Sgiacomo.travaglini@arm.com    // Check for routing to AArch64: this happens if the
77412403Sgiacomo.travaglini@arm.com    // target exception level (where the trap will be handled)
77512403Sgiacomo.travaglini@arm.com    // is using aarch64
77612403Sgiacomo.travaglini@arm.com    if (ELIs64(tc, targetEL)) {
77712403Sgiacomo.travaglini@arm.com        return checkForWFxTrap64(tc, targetEL, isWfe);
77812403Sgiacomo.travaglini@arm.com    }
77912403Sgiacomo.travaglini@arm.com
78012403Sgiacomo.travaglini@arm.com    // Check if processor needs to trap at selected exception level
78112403Sgiacomo.travaglini@arm.com    bool trap = isWFxTrapping(tc, targetEL, isWfe);
78212403Sgiacomo.travaglini@arm.com
78312403Sgiacomo.travaglini@arm.com    if (trap) {
78412403Sgiacomo.travaglini@arm.com        uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */
78512403Sgiacomo.travaglini@arm.com                              0x1E00000;  /* WFI Instruction syndrome */
78612403Sgiacomo.travaglini@arm.com        switch (targetEL) {
78712403Sgiacomo.travaglini@arm.com          case EL1:
78812403Sgiacomo.travaglini@arm.com            return std::make_shared<UndefinedInstruction>(
78912403Sgiacomo.travaglini@arm.com                machInst, iss,
79012403Sgiacomo.travaglini@arm.com                EC_TRAPPED_WFI_WFE, mnemonic);
79112403Sgiacomo.travaglini@arm.com          case EL2:
79212403Sgiacomo.travaglini@arm.com            return std::make_shared<HypervisorTrap>(machInst, iss,
79312403Sgiacomo.travaglini@arm.com                                                    EC_TRAPPED_WFI_WFE);
79412403Sgiacomo.travaglini@arm.com          case EL3:
79512403Sgiacomo.travaglini@arm.com            return std::make_shared<SecureMonitorTrap>(machInst, iss,
79612403Sgiacomo.travaglini@arm.com                                                       EC_TRAPPED_WFI_WFE);
79712403Sgiacomo.travaglini@arm.com          default:
79812403Sgiacomo.travaglini@arm.com            panic("Unrecognized Exception Level: %d\n", targetEL);
79912403Sgiacomo.travaglini@arm.com        }
80012403Sgiacomo.travaglini@arm.com    }
80112403Sgiacomo.travaglini@arm.com
80212403Sgiacomo.travaglini@arm.com    return NoFault;
80312403Sgiacomo.travaglini@arm.com}
80412403Sgiacomo.travaglini@arm.com
80512403Sgiacomo.travaglini@arm.comFault
80612403Sgiacomo.travaglini@arm.comArmStaticInst::checkForWFxTrap64(ThreadContext *tc,
80712403Sgiacomo.travaglini@arm.com                                 ExceptionLevel targetEL,
80812403Sgiacomo.travaglini@arm.com                                 bool isWfe) const
80912403Sgiacomo.travaglini@arm.com{
81012403Sgiacomo.travaglini@arm.com    // Check if target exception level is implemented.
81112403Sgiacomo.travaglini@arm.com    assert(ArmSystem::haveEL(tc, targetEL));
81212403Sgiacomo.travaglini@arm.com
81312403Sgiacomo.travaglini@arm.com    // Check if processor needs to trap at selected exception level
81412403Sgiacomo.travaglini@arm.com    bool trap = isWFxTrapping(tc, targetEL, isWfe);
81512403Sgiacomo.travaglini@arm.com
81612403Sgiacomo.travaglini@arm.com    if (trap) {
81712403Sgiacomo.travaglini@arm.com        uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */
81812403Sgiacomo.travaglini@arm.com                              0x1E00000;  /* WFI Instruction syndrome */
81912403Sgiacomo.travaglini@arm.com        switch (targetEL) {
82012403Sgiacomo.travaglini@arm.com          case EL1:
82112403Sgiacomo.travaglini@arm.com            return std::make_shared<SupervisorTrap>(machInst, iss,
82212403Sgiacomo.travaglini@arm.com                                                    EC_TRAPPED_WFI_WFE);
82312403Sgiacomo.travaglini@arm.com          case EL2:
82412403Sgiacomo.travaglini@arm.com            return std::make_shared<HypervisorTrap>(machInst, iss,
82512403Sgiacomo.travaglini@arm.com                                                    EC_TRAPPED_WFI_WFE);
82612403Sgiacomo.travaglini@arm.com          case EL3:
82712403Sgiacomo.travaglini@arm.com            return std::make_shared<SecureMonitorTrap>(machInst, iss,
82812403Sgiacomo.travaglini@arm.com                                                       EC_TRAPPED_WFI_WFE);
82912403Sgiacomo.travaglini@arm.com          default:
83012403Sgiacomo.travaglini@arm.com            panic("Unrecognized Exception Level: %d\n", targetEL);
83112403Sgiacomo.travaglini@arm.com        }
83212403Sgiacomo.travaglini@arm.com    }
83312403Sgiacomo.travaglini@arm.com
83412403Sgiacomo.travaglini@arm.com    return NoFault;
83512403Sgiacomo.travaglini@arm.com}
83612403Sgiacomo.travaglini@arm.com
83712403Sgiacomo.travaglini@arm.comFault
83812403Sgiacomo.travaglini@arm.comArmStaticInst::trapWFx(ThreadContext *tc,
83912403Sgiacomo.travaglini@arm.com                       CPSR cpsr, SCR scr,
84012403Sgiacomo.travaglini@arm.com                       bool isWfe) const
84112403Sgiacomo.travaglini@arm.com{
84212403Sgiacomo.travaglini@arm.com    Fault fault = NoFault;
84312403Sgiacomo.travaglini@arm.com    if (cpsr.el == EL0) {
84412403Sgiacomo.travaglini@arm.com        fault = checkForWFxTrap32(tc, EL1, isWfe);
84512403Sgiacomo.travaglini@arm.com    }
84612403Sgiacomo.travaglini@arm.com
84712403Sgiacomo.travaglini@arm.com    if ((fault == NoFault) &&
84812403Sgiacomo.travaglini@arm.com        ArmSystem::haveEL(tc, EL2) && !inSecureState(scr, cpsr) &&
84912403Sgiacomo.travaglini@arm.com        ((cpsr.el == EL0) || (cpsr.el == EL1))) {
85012403Sgiacomo.travaglini@arm.com
85112403Sgiacomo.travaglini@arm.com        fault = checkForWFxTrap32(tc, EL2, isWfe);
85212403Sgiacomo.travaglini@arm.com    }
85312403Sgiacomo.travaglini@arm.com
85412403Sgiacomo.travaglini@arm.com    if ((fault == NoFault) &&
85512403Sgiacomo.travaglini@arm.com        ArmSystem::haveEL(tc, EL3) && cpsr.el != EL3) {
85612403Sgiacomo.travaglini@arm.com        fault = checkForWFxTrap32(tc, EL3, isWfe);
85712403Sgiacomo.travaglini@arm.com    }
85812403Sgiacomo.travaglini@arm.com
85912403Sgiacomo.travaglini@arm.com    return fault;
86012403Sgiacomo.travaglini@arm.com}
86111513Sandreas.sandberg@arm.com
86212498Sgiacomo.travaglini@arm.comFault
86312498Sgiacomo.travaglini@arm.comArmStaticInst::checkSETENDEnabled(ThreadContext *tc, CPSR cpsr) const
86412498Sgiacomo.travaglini@arm.com{
86512498Sgiacomo.travaglini@arm.com    bool setend_disabled(false);
86612498Sgiacomo.travaglini@arm.com    ExceptionLevel pstateEL = (ExceptionLevel)(uint8_t)(cpsr.el);
86712498Sgiacomo.travaglini@arm.com
86812498Sgiacomo.travaglini@arm.com    if (pstateEL == EL2) {
86912498Sgiacomo.travaglini@arm.com       setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(MISCREG_HSCTLR)).sed;
87012498Sgiacomo.travaglini@arm.com    } else {
87112498Sgiacomo.travaglini@arm.com        // Please note: in the armarm pseudocode there is a distinction
87212498Sgiacomo.travaglini@arm.com        // whether EL1 is aarch32 or aarch64:
87312498Sgiacomo.travaglini@arm.com        // if ELUsingAArch32(EL1) then SCTLR.SED else SCTLR[].SED;
87412498Sgiacomo.travaglini@arm.com        // Considering that SETEND is aarch32 only, ELUsingAArch32(EL1)
87512498Sgiacomo.travaglini@arm.com        // will always be true (hence using SCTLR.SED) except for
87612498Sgiacomo.travaglini@arm.com        // instruction executed at EL0, and with an AArch64 EL1.
87712498Sgiacomo.travaglini@arm.com        // In this case SCTLR_EL1 will be used. In gem5 the register is
87812498Sgiacomo.travaglini@arm.com        // mapped to SCTLR_ns. We can safely use SCTLR and choose the
87912498Sgiacomo.travaglini@arm.com        // appropriate bank version.
88012498Sgiacomo.travaglini@arm.com
88112498Sgiacomo.travaglini@arm.com        // Get the index of the banked version of SCTLR:
88212498Sgiacomo.travaglini@arm.com        // SCTLR_s or SCTLR_ns.
88312499Sgiacomo.travaglini@arm.com        auto banked_sctlr = snsBankedIndex(
88412498Sgiacomo.travaglini@arm.com            MISCREG_SCTLR, tc, !inSecureState(tc));
88512498Sgiacomo.travaglini@arm.com
88612498Sgiacomo.travaglini@arm.com        // SCTLR.SED bit is enabling/disabling the ue of SETEND instruction.
88712498Sgiacomo.travaglini@arm.com        setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(banked_sctlr)).sed;
88812498Sgiacomo.travaglini@arm.com    }
88912498Sgiacomo.travaglini@arm.com
89012498Sgiacomo.travaglini@arm.com    return setend_disabled ? undefinedFault32(tc, pstateEL) :
89112498Sgiacomo.travaglini@arm.com                             NoFault;
89212498Sgiacomo.travaglini@arm.com}
89312498Sgiacomo.travaglini@arm.com
89412498Sgiacomo.travaglini@arm.comFault
89512498Sgiacomo.travaglini@arm.comArmStaticInst::undefinedFault32(ThreadContext *tc,
89612498Sgiacomo.travaglini@arm.com                                ExceptionLevel pstateEL) const
89712498Sgiacomo.travaglini@arm.com{
89812498Sgiacomo.travaglini@arm.com    // Even if we are running in aarch32, the fault might be dealt with in
89912498Sgiacomo.travaglini@arm.com    // aarch64 ISA.
90012498Sgiacomo.travaglini@arm.com    if (generalExceptionsToAArch64(tc, pstateEL)) {
90112498Sgiacomo.travaglini@arm.com        return undefinedFault64(tc, pstateEL);
90212498Sgiacomo.travaglini@arm.com    } else {
90312498Sgiacomo.travaglini@arm.com        // Please note: according to the ARM ARM pseudocode we should handle
90412498Sgiacomo.travaglini@arm.com        // the case when EL2 is aarch64 and HCR.TGE is 1 as well.
90512498Sgiacomo.travaglini@arm.com        // However this case is already handled by the routeToHyp method in
90612498Sgiacomo.travaglini@arm.com        // ArmFault class.
90712498Sgiacomo.travaglini@arm.com        return std::make_shared<UndefinedInstruction>(
90812498Sgiacomo.travaglini@arm.com            machInst, 0,
90912498Sgiacomo.travaglini@arm.com            EC_UNKNOWN, mnemonic);
91012498Sgiacomo.travaglini@arm.com    }
91112498Sgiacomo.travaglini@arm.com}
91212498Sgiacomo.travaglini@arm.com
91312498Sgiacomo.travaglini@arm.comFault
91412498Sgiacomo.travaglini@arm.comArmStaticInst::undefinedFault64(ThreadContext *tc,
91512498Sgiacomo.travaglini@arm.com                                ExceptionLevel pstateEL) const
91612498Sgiacomo.travaglini@arm.com{
91712498Sgiacomo.travaglini@arm.com    switch (pstateEL) {
91812498Sgiacomo.travaglini@arm.com      case EL0:
91912498Sgiacomo.travaglini@arm.com      case EL1:
92012498Sgiacomo.travaglini@arm.com        return std::make_shared<SupervisorTrap>(machInst, 0, EC_UNKNOWN);
92112498Sgiacomo.travaglini@arm.com      case EL2:
92212498Sgiacomo.travaglini@arm.com        return std::make_shared<HypervisorTrap>(machInst, 0, EC_UNKNOWN);
92312498Sgiacomo.travaglini@arm.com      case EL3:
92412498Sgiacomo.travaglini@arm.com        return std::make_shared<SecureMonitorTrap>(machInst, 0, EC_UNKNOWN);
92512498Sgiacomo.travaglini@arm.com      default:
92612498Sgiacomo.travaglini@arm.com        panic("Unrecognized Exception Level: %d\n", pstateEL);
92712498Sgiacomo.travaglini@arm.com        break;
92812498Sgiacomo.travaglini@arm.com    }
92912498Sgiacomo.travaglini@arm.com
93012498Sgiacomo.travaglini@arm.com    return NoFault;
93112498Sgiacomo.travaglini@arm.com}
93212498Sgiacomo.travaglini@arm.com
93311514Sandreas.sandberg@arm.comstatic uint8_t
93411514Sandreas.sandberg@arm.comgetRestoredITBits(ThreadContext *tc, CPSR spsr)
93511514Sandreas.sandberg@arm.com{
93611514Sandreas.sandberg@arm.com    // See: shared/functions/system/RestoredITBits in the ARM ARM
93711514Sandreas.sandberg@arm.com
93811514Sandreas.sandberg@arm.com    const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode);
93911514Sandreas.sandberg@arm.com    const uint8_t it = itState(spsr);
94011514Sandreas.sandberg@arm.com
94111514Sandreas.sandberg@arm.com    if (!spsr.t || spsr.il)
94211514Sandreas.sandberg@arm.com        return 0;
94311514Sandreas.sandberg@arm.com
94411514Sandreas.sandberg@arm.com    // The IT bits are forced to zero when they are set to a reserved
94511514Sandreas.sandberg@arm.com    // value.
94611514Sandreas.sandberg@arm.com    if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0)
94711514Sandreas.sandberg@arm.com        return 0;
94811514Sandreas.sandberg@arm.com
94911514Sandreas.sandberg@arm.com    const bool itd = el == EL2 ?
95011514Sandreas.sandberg@arm.com        ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd :
95111514Sandreas.sandberg@arm.com        ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd;
95211514Sandreas.sandberg@arm.com
95311514Sandreas.sandberg@arm.com    // The IT bits are forced to zero when returning to A32 state, or
95411514Sandreas.sandberg@arm.com    // when returning to an EL with the ITD bit set to 1, and the IT
95511514Sandreas.sandberg@arm.com    // bits are describing a multi-instruction block.
95611514Sandreas.sandberg@arm.com    if (itd && bits(it, 2, 0) != 0)
95711514Sandreas.sandberg@arm.com        return 0;
95811514Sandreas.sandberg@arm.com
95911514Sandreas.sandberg@arm.com    return it;
96011513Sandreas.sandberg@arm.com}
96111514Sandreas.sandberg@arm.com
96211514Sandreas.sandberg@arm.comstatic bool
96311514Sandreas.sandberg@arm.comillegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
96411514Sandreas.sandberg@arm.com{
96511514Sandreas.sandberg@arm.com    const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode;
96611514Sandreas.sandberg@arm.com    if (badMode(mode))
96711514Sandreas.sandberg@arm.com        return true;
96811514Sandreas.sandberg@arm.com
96911514Sandreas.sandberg@arm.com    const OperatingMode cur_mode = (OperatingMode) (uint8_t)cpsr.mode;
97011514Sandreas.sandberg@arm.com    const ExceptionLevel target_el = opModeToEL(mode);
97112497Sgiacomo.travaglini@arm.com
97212497Sgiacomo.travaglini@arm.com    HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
97312497Sgiacomo.travaglini@arm.com    SCR scr = ((SCR)tc->readMiscReg(MISCREG_SCR_EL3));
97412497Sgiacomo.travaglini@arm.com
97511514Sandreas.sandberg@arm.com    if (target_el > opModeToEL(cur_mode))
97611514Sandreas.sandberg@arm.com        return true;
97711514Sandreas.sandberg@arm.com
97812497Sgiacomo.travaglini@arm.com    if (!ArmSystem::haveEL(tc, target_el))
97911514Sandreas.sandberg@arm.com        return true;
98011514Sandreas.sandberg@arm.com
98112497Sgiacomo.travaglini@arm.com    if (target_el == EL1 && ArmSystem::haveEL(tc, EL2) && scr.ns && hcr.tge)
98212497Sgiacomo.travaglini@arm.com        return true;
98312497Sgiacomo.travaglini@arm.com
98412497Sgiacomo.travaglini@arm.com    if (target_el == EL2 && ArmSystem::haveEL(tc, EL3) && !scr.ns)
98512497Sgiacomo.travaglini@arm.com        return true;
98612497Sgiacomo.travaglini@arm.com
98712497Sgiacomo.travaglini@arm.com    bool spsr_mode_is_aarch32 = (spsr.width == 1);
98812497Sgiacomo.travaglini@arm.com    bool known, target_el_is_aarch32;
98912497Sgiacomo.travaglini@arm.com    std::tie(known, target_el_is_aarch32) = ELUsingAArch32K(tc, target_el);
99012497Sgiacomo.travaglini@arm.com    assert(known || (target_el == EL0 && ELIs64(tc, EL1)));
99112497Sgiacomo.travaglini@arm.com
99212497Sgiacomo.travaglini@arm.com    if (known && (spsr_mode_is_aarch32 != target_el_is_aarch32))
99311514Sandreas.sandberg@arm.com        return true;
99411514Sandreas.sandberg@arm.com
99511514Sandreas.sandberg@arm.com    if (!spsr.width) {
99611514Sandreas.sandberg@arm.com        // aarch64
99711514Sandreas.sandberg@arm.com        if (!ArmSystem::highestELIs64(tc))
99811514Sandreas.sandberg@arm.com            return true;
99911514Sandreas.sandberg@arm.com        if (spsr & 0x2)
100011514Sandreas.sandberg@arm.com            return true;
100111514Sandreas.sandberg@arm.com        if (target_el == EL0 && spsr.sp)
100211514Sandreas.sandberg@arm.com            return true;
100311514Sandreas.sandberg@arm.com    } else {
100412497Sgiacomo.travaglini@arm.com        // aarch32
100511514Sandreas.sandberg@arm.com        return badMode32(mode);
100611514Sandreas.sandberg@arm.com    }
100711514Sandreas.sandberg@arm.com
100811514Sandreas.sandberg@arm.com    return false;
100911514Sandreas.sandberg@arm.com}
101011514Sandreas.sandberg@arm.com
101111514Sandreas.sandberg@arm.comCPSR
101211514Sandreas.sandberg@arm.comArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
101311514Sandreas.sandberg@arm.com{
101411514Sandreas.sandberg@arm.com    CPSR new_cpsr = 0;
101511514Sandreas.sandberg@arm.com
101611514Sandreas.sandberg@arm.com    // gem5 doesn't implement single-stepping, so force the SS bit to
101711514Sandreas.sandberg@arm.com    // 0.
101811514Sandreas.sandberg@arm.com    new_cpsr.ss = 0;
101911514Sandreas.sandberg@arm.com
102011514Sandreas.sandberg@arm.com    if (illegalExceptionReturn(tc, cpsr, spsr)) {
102112510Sgiacomo.travaglini@arm.com        // If the SPSR specifies an illegal exception return,
102212510Sgiacomo.travaglini@arm.com        // then PSTATE.{M, nRW, EL, SP} are unchanged and PSTATE.IL
102312510Sgiacomo.travaglini@arm.com        // is set to 1.
102411514Sandreas.sandberg@arm.com        new_cpsr.il = 1;
102512510Sgiacomo.travaglini@arm.com        if (cpsr.width) {
102612510Sgiacomo.travaglini@arm.com            new_cpsr.mode = cpsr.mode;
102712510Sgiacomo.travaglini@arm.com        } else {
102812510Sgiacomo.travaglini@arm.com            new_cpsr.width = cpsr.width;
102912510Sgiacomo.travaglini@arm.com            new_cpsr.el = cpsr.el;
103012510Sgiacomo.travaglini@arm.com            new_cpsr.sp = cpsr.sp;
103112510Sgiacomo.travaglini@arm.com        }
103211514Sandreas.sandberg@arm.com    } else {
103311514Sandreas.sandberg@arm.com        new_cpsr.il = spsr.il;
103411514Sandreas.sandberg@arm.com        if (spsr.width && badMode32((OperatingMode)(uint8_t)spsr.mode)) {
103511514Sandreas.sandberg@arm.com            new_cpsr.il = 1;
103611514Sandreas.sandberg@arm.com        } else if (spsr.width) {
103711514Sandreas.sandberg@arm.com            new_cpsr.mode = spsr.mode;
103811514Sandreas.sandberg@arm.com        } else {
103911514Sandreas.sandberg@arm.com            new_cpsr.el = spsr.el;
104011514Sandreas.sandberg@arm.com            new_cpsr.sp = spsr.sp;
104111514Sandreas.sandberg@arm.com        }
104211514Sandreas.sandberg@arm.com    }
104311514Sandreas.sandberg@arm.com
104411514Sandreas.sandberg@arm.com    new_cpsr.nz = spsr.nz;
104511514Sandreas.sandberg@arm.com    new_cpsr.c = spsr.c;
104611514Sandreas.sandberg@arm.com    new_cpsr.v = spsr.v;
104711514Sandreas.sandberg@arm.com    if (new_cpsr.width) {
104811514Sandreas.sandberg@arm.com        // aarch32
104911514Sandreas.sandberg@arm.com        const ITSTATE it = getRestoredITBits(tc, spsr);
105011514Sandreas.sandberg@arm.com        new_cpsr.q = spsr.q;
105111514Sandreas.sandberg@arm.com        new_cpsr.ge = spsr.ge;
105211514Sandreas.sandberg@arm.com        new_cpsr.e = spsr.e;
105311514Sandreas.sandberg@arm.com        new_cpsr.aif = spsr.aif;
105411514Sandreas.sandberg@arm.com        new_cpsr.t = spsr.t;
105511514Sandreas.sandberg@arm.com        new_cpsr.it2 = it.top6;
105611514Sandreas.sandberg@arm.com        new_cpsr.it1 = it.bottom2;
105711514Sandreas.sandberg@arm.com    } else {
105811514Sandreas.sandberg@arm.com        // aarch64
105911514Sandreas.sandberg@arm.com        new_cpsr.daif = spsr.daif;
106011514Sandreas.sandberg@arm.com    }
106111514Sandreas.sandberg@arm.com
106211514Sandreas.sandberg@arm.com    return new_cpsr;
106311514Sandreas.sandberg@arm.com}
106411514Sandreas.sandberg@arm.com
106512498Sgiacomo.travaglini@arm.combool
106612498Sgiacomo.travaglini@arm.comArmStaticInst::generalExceptionsToAArch64(ThreadContext *tc,
106712498Sgiacomo.travaglini@arm.com                                          ExceptionLevel pstateEL) const
106812498Sgiacomo.travaglini@arm.com{
106912498Sgiacomo.travaglini@arm.com    // Returns TRUE if exceptions normally routed to EL1 are being handled
107012498Sgiacomo.travaglini@arm.com    // at an Exception level using AArch64, because either EL1 is using
107112498Sgiacomo.travaglini@arm.com    // AArch64 or TGE is in force and EL2 is using AArch64.
107212498Sgiacomo.travaglini@arm.com    HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
107312498Sgiacomo.travaglini@arm.com    return (pstateEL == EL0 && !ELIs32(tc, EL1)) ||
107412498Sgiacomo.travaglini@arm.com           (ArmSystem::haveEL(tc, EL2) && !inSecureState(tc) &&
107512498Sgiacomo.travaglini@arm.com               !ELIs32(tc, EL2) && hcr.tge);
107612498Sgiacomo.travaglini@arm.com}
107711514Sandreas.sandberg@arm.com
107811514Sandreas.sandberg@arm.com
107911514Sandreas.sandberg@arm.com}
1080