17094Sgblack@eecs.umich.edu/*
214128Sgiacomo.travaglini@arm.com * Copyright (c) 2010-2014, 2016-2019 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"
4713759Sgiacomo.gabrielli@arm.com#include "arch/arm/isa.hh"
486255Sgblack@eecs.umich.edu#include "base/condcodes.hh"
496712Snate@binkert.org#include "base/cprintf.hh"
5011793Sbrandon.potter@amd.com#include "base/loader/symtab.hh"
519913Ssteve.reinhardt@amd.com#include "cpu/reg_class.hh"
526253Sgblack@eecs.umich.edu
536253Sgblack@eecs.umich.edunamespace ArmISA
546253Sgblack@eecs.umich.edu{
556254Sgblack@eecs.umich.edu// Shift Rm by an immediate value
566254Sgblack@eecs.umich.eduint32_t
577148Sgblack@eecs.umich.eduArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt,
587094Sgblack@eecs.umich.edu                                uint32_t type, uint32_t cfval) const
596254Sgblack@eecs.umich.edu{
606255Sgblack@eecs.umich.edu    assert(shamt < 32);
616255Sgblack@eecs.umich.edu    ArmShiftType shiftType;
626255Sgblack@eecs.umich.edu    shiftType = (ArmShiftType)type;
636254Sgblack@eecs.umich.edu
646254Sgblack@eecs.umich.edu    switch (shiftType)
656254Sgblack@eecs.umich.edu    {
666255Sgblack@eecs.umich.edu      case LSL:
676255Sgblack@eecs.umich.edu        return base << shamt;
686255Sgblack@eecs.umich.edu      case LSR:
696255Sgblack@eecs.umich.edu        if (shamt == 0)
706255Sgblack@eecs.umich.edu            return 0;
716255Sgblack@eecs.umich.edu        else
726255Sgblack@eecs.umich.edu            return base >> shamt;
736255Sgblack@eecs.umich.edu      case ASR:
746255Sgblack@eecs.umich.edu        if (shamt == 0)
757182Sgblack@eecs.umich.edu            return (base >> 31) | -((base & (1 << 31)) >> 31);
766255Sgblack@eecs.umich.edu        else
777182Sgblack@eecs.umich.edu            return (base >> shamt) | -((base & (1 << 31)) >> shamt);
786255Sgblack@eecs.umich.edu      case ROR:
796255Sgblack@eecs.umich.edu        if (shamt == 0)
806255Sgblack@eecs.umich.edu            return (cfval << 31) | (base >> 1); // RRX
816255Sgblack@eecs.umich.edu        else
826255Sgblack@eecs.umich.edu            return (base << (32 - shamt)) | (base >> shamt);
836255Sgblack@eecs.umich.edu      default:
846712Snate@binkert.org        ccprintf(std::cerr, "Unhandled shift type\n");
856255Sgblack@eecs.umich.edu        exit(1);
866255Sgblack@eecs.umich.edu        break;
876254Sgblack@eecs.umich.edu    }
886254Sgblack@eecs.umich.edu    return 0;
896254Sgblack@eecs.umich.edu}
906254Sgblack@eecs.umich.edu
9110037SARM gem5 Developersint64_t
9210037SARM gem5 DevelopersArmStaticInst::shiftReg64(uint64_t base, uint64_t shiftAmt,
9310037SARM gem5 Developers                          ArmShiftType type, uint8_t width) const
9410037SARM gem5 Developers{
9510037SARM gem5 Developers    shiftAmt = shiftAmt % width;
9610037SARM gem5 Developers    ArmShiftType shiftType;
9710037SARM gem5 Developers    shiftType = (ArmShiftType)type;
9810037SARM gem5 Developers
9910037SARM gem5 Developers    switch (shiftType)
10010037SARM gem5 Developers    {
10110037SARM gem5 Developers      case LSL:
10210037SARM gem5 Developers        return base << shiftAmt;
10310037SARM gem5 Developers      case LSR:
10410037SARM gem5 Developers        if (shiftAmt == 0)
10510037SARM gem5 Developers            return base;
10610037SARM gem5 Developers        else
10710037SARM gem5 Developers            return (base & mask(width)) >> shiftAmt;
10810037SARM gem5 Developers      case ASR:
10910037SARM gem5 Developers        if (shiftAmt == 0) {
11010037SARM gem5 Developers            return base;
11110037SARM gem5 Developers        } else {
11210037SARM gem5 Developers            int sign_bit = bits(base, intWidth - 1);
11310037SARM gem5 Developers            base >>= shiftAmt;
11410037SARM gem5 Developers            base = sign_bit ? (base | ~mask(intWidth - shiftAmt)) : base;
11510037SARM gem5 Developers            return base & mask(intWidth);
11610037SARM gem5 Developers        }
11710037SARM gem5 Developers      case ROR:
11810037SARM gem5 Developers        if (shiftAmt == 0)
11910037SARM gem5 Developers            return base;
12010037SARM gem5 Developers        else
12110037SARM gem5 Developers            return (base << (width - shiftAmt)) | (base >> shiftAmt);
12210037SARM gem5 Developers      default:
12310037SARM gem5 Developers        ccprintf(std::cerr, "Unhandled shift type\n");
12410037SARM gem5 Developers        exit(1);
12510037SARM gem5 Developers        break;
12610037SARM gem5 Developers    }
12710037SARM gem5 Developers    return 0;
12810037SARM gem5 Developers}
12910037SARM gem5 Developers
13010037SARM gem5 Developersint64_t
13110037SARM gem5 DevelopersArmStaticInst::extendReg64(uint64_t base, ArmExtendType type,
13210037SARM gem5 Developers                           uint64_t shiftAmt, uint8_t width) const
13310037SARM gem5 Developers{
13410037SARM gem5 Developers    bool sign_extend = false;
13510037SARM gem5 Developers    int len = 0;
13610037SARM gem5 Developers    switch (type) {
13710037SARM gem5 Developers      case UXTB:
13810037SARM gem5 Developers        len = 8;
13910037SARM gem5 Developers        break;
14010037SARM gem5 Developers      case UXTH:
14110037SARM gem5 Developers        len = 16;
14210037SARM gem5 Developers        break;
14310037SARM gem5 Developers      case UXTW:
14410037SARM gem5 Developers        len = 32;
14510037SARM gem5 Developers        break;
14610037SARM gem5 Developers      case UXTX:
14710037SARM gem5 Developers        len = 64;
14810037SARM gem5 Developers        break;
14910037SARM gem5 Developers      case SXTB:
15010037SARM gem5 Developers        len = 8;
15110037SARM gem5 Developers        sign_extend = true;
15210037SARM gem5 Developers        break;
15310037SARM gem5 Developers      case SXTH:
15410037SARM gem5 Developers        len = 16;
15510037SARM gem5 Developers        sign_extend = true;
15610037SARM gem5 Developers        break;
15710037SARM gem5 Developers      case SXTW:
15810037SARM gem5 Developers        len = 32;
15910037SARM gem5 Developers        sign_extend = true;
16010037SARM gem5 Developers        break;
16110037SARM gem5 Developers      case SXTX:
16210037SARM gem5 Developers        len = 64;
16310037SARM gem5 Developers        sign_extend = true;
16410037SARM gem5 Developers        break;
16510037SARM gem5 Developers    }
16610037SARM gem5 Developers    len = len <= width - shiftAmt ? len : width - shiftAmt;
16710037SARM gem5 Developers    uint64_t tmp = (uint64_t) bits(base, len - 1, 0) << shiftAmt;
16810037SARM gem5 Developers    if (sign_extend) {
16910037SARM gem5 Developers        int sign_bit = bits(tmp, len + shiftAmt - 1);
17010037SARM gem5 Developers        tmp = sign_bit ? (tmp | ~mask(len + shiftAmt)) : tmp;
17110037SARM gem5 Developers    }
17210037SARM gem5 Developers    return tmp & mask(width);
17310037SARM gem5 Developers}
17410037SARM gem5 Developers
1756254Sgblack@eecs.umich.edu// Shift Rm by Rs
1766254Sgblack@eecs.umich.eduint32_t
1777148Sgblack@eecs.umich.eduArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt,
1787094Sgblack@eecs.umich.edu                               uint32_t type, uint32_t cfval) const
1796254Sgblack@eecs.umich.edu{
1806254Sgblack@eecs.umich.edu    enum ArmShiftType shiftType;
1816254Sgblack@eecs.umich.edu    shiftType = (enum ArmShiftType) type;
1826254Sgblack@eecs.umich.edu
1836254Sgblack@eecs.umich.edu    switch (shiftType)
1846254Sgblack@eecs.umich.edu    {
1856255Sgblack@eecs.umich.edu      case LSL:
1866255Sgblack@eecs.umich.edu        if (shamt >= 32)
1876255Sgblack@eecs.umich.edu            return 0;
1886255Sgblack@eecs.umich.edu        else
1896255Sgblack@eecs.umich.edu            return base << shamt;
1906255Sgblack@eecs.umich.edu      case LSR:
1916255Sgblack@eecs.umich.edu        if (shamt >= 32)
1926255Sgblack@eecs.umich.edu            return 0;
1936255Sgblack@eecs.umich.edu        else
1946255Sgblack@eecs.umich.edu            return base >> shamt;
1956255Sgblack@eecs.umich.edu      case ASR:
1966255Sgblack@eecs.umich.edu        if (shamt >= 32)
1977182Sgblack@eecs.umich.edu            return (base >> 31) | -((base & (1 << 31)) >> 31);
1986255Sgblack@eecs.umich.edu        else
1997182Sgblack@eecs.umich.edu            return (base >> shamt) | -((base & (1 << 31)) >> shamt);
2006255Sgblack@eecs.umich.edu      case ROR:
2016255Sgblack@eecs.umich.edu        shamt = shamt & 0x1f;
2026255Sgblack@eecs.umich.edu        if (shamt == 0)
2036255Sgblack@eecs.umich.edu            return base;
2046255Sgblack@eecs.umich.edu        else
2056255Sgblack@eecs.umich.edu            return (base << (32 - shamt)) | (base >> shamt);
2066255Sgblack@eecs.umich.edu      default:
2076712Snate@binkert.org        ccprintf(std::cerr, "Unhandled shift type\n");
2086255Sgblack@eecs.umich.edu        exit(1);
2096255Sgblack@eecs.umich.edu        break;
2106254Sgblack@eecs.umich.edu    }
2116254Sgblack@eecs.umich.edu    return 0;
2126254Sgblack@eecs.umich.edu}
2136254Sgblack@eecs.umich.edu
2146254Sgblack@eecs.umich.edu
2156254Sgblack@eecs.umich.edu// Generate C for a shift by immediate
2166255Sgblack@eecs.umich.edubool
2177148Sgblack@eecs.umich.eduArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt,
2187094Sgblack@eecs.umich.edu                                   uint32_t type, uint32_t cfval) const
2196254Sgblack@eecs.umich.edu{
2206254Sgblack@eecs.umich.edu    enum ArmShiftType shiftType;
2216254Sgblack@eecs.umich.edu    shiftType = (enum ArmShiftType) type;
2226254Sgblack@eecs.umich.edu
2236254Sgblack@eecs.umich.edu    switch (shiftType)
2246254Sgblack@eecs.umich.edu    {
2256255Sgblack@eecs.umich.edu      case LSL:
2266255Sgblack@eecs.umich.edu        if (shamt == 0)
2276255Sgblack@eecs.umich.edu            return cfval;
2286255Sgblack@eecs.umich.edu        else
2296254Sgblack@eecs.umich.edu            return (base >> (32 - shamt)) & 1;
2306255Sgblack@eecs.umich.edu      case LSR:
2316255Sgblack@eecs.umich.edu        if (shamt == 0)
2326255Sgblack@eecs.umich.edu            return (base >> 31);
2336255Sgblack@eecs.umich.edu        else
2346255Sgblack@eecs.umich.edu            return (base >> (shamt - 1)) & 1;
2356255Sgblack@eecs.umich.edu      case ASR:
2366255Sgblack@eecs.umich.edu        if (shamt == 0)
2376255Sgblack@eecs.umich.edu            return (base >> 31);
2386255Sgblack@eecs.umich.edu        else
2396255Sgblack@eecs.umich.edu            return (base >> (shamt - 1)) & 1;
2406255Sgblack@eecs.umich.edu      case ROR:
2416255Sgblack@eecs.umich.edu        shamt = shamt & 0x1f;
2426255Sgblack@eecs.umich.edu        if (shamt == 0)
2436255Sgblack@eecs.umich.edu            return (base & 1); // RRX
2446255Sgblack@eecs.umich.edu        else
2456255Sgblack@eecs.umich.edu            return (base >> (shamt - 1)) & 1;
2466255Sgblack@eecs.umich.edu      default:
2476712Snate@binkert.org        ccprintf(std::cerr, "Unhandled shift type\n");
2486255Sgblack@eecs.umich.edu        exit(1);
2496255Sgblack@eecs.umich.edu        break;
2506254Sgblack@eecs.umich.edu    }
2516254Sgblack@eecs.umich.edu    return 0;
2526254Sgblack@eecs.umich.edu}
2536254Sgblack@eecs.umich.edu
2546254Sgblack@eecs.umich.edu
2556254Sgblack@eecs.umich.edu// Generate C for a shift by Rs
2566255Sgblack@eecs.umich.edubool
2577148Sgblack@eecs.umich.eduArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
2587094Sgblack@eecs.umich.edu                                  uint32_t type, uint32_t cfval) const
2596254Sgblack@eecs.umich.edu{
2606254Sgblack@eecs.umich.edu    enum ArmShiftType shiftType;
2616254Sgblack@eecs.umich.edu    shiftType = (enum ArmShiftType) type;
2626254Sgblack@eecs.umich.edu
2636255Sgblack@eecs.umich.edu    if (shamt == 0)
2646255Sgblack@eecs.umich.edu        return cfval;
2656255Sgblack@eecs.umich.edu
2666254Sgblack@eecs.umich.edu    switch (shiftType)
2676254Sgblack@eecs.umich.edu    {
2686255Sgblack@eecs.umich.edu      case LSL:
2696255Sgblack@eecs.umich.edu        if (shamt > 32)
2706255Sgblack@eecs.umich.edu            return 0;
2716255Sgblack@eecs.umich.edu        else
2726255Sgblack@eecs.umich.edu            return (base >> (32 - shamt)) & 1;
2736255Sgblack@eecs.umich.edu      case LSR:
2746255Sgblack@eecs.umich.edu        if (shamt > 32)
2756255Sgblack@eecs.umich.edu            return 0;
2766255Sgblack@eecs.umich.edu        else
2776255Sgblack@eecs.umich.edu            return (base >> (shamt - 1)) & 1;
2786255Sgblack@eecs.umich.edu      case ASR:
2796255Sgblack@eecs.umich.edu        if (shamt > 32)
2806255Sgblack@eecs.umich.edu            shamt = 32;
2816255Sgblack@eecs.umich.edu        return (base >> (shamt - 1)) & 1;
2826255Sgblack@eecs.umich.edu      case ROR:
2836255Sgblack@eecs.umich.edu        shamt = shamt & 0x1f;
2846255Sgblack@eecs.umich.edu        if (shamt == 0)
2856255Sgblack@eecs.umich.edu            shamt = 32;
2866255Sgblack@eecs.umich.edu        return (base >> (shamt - 1)) & 1;
2876255Sgblack@eecs.umich.edu      default:
2886712Snate@binkert.org        ccprintf(std::cerr, "Unhandled shift type\n");
2896255Sgblack@eecs.umich.edu        exit(1);
2906255Sgblack@eecs.umich.edu        break;
2916254Sgblack@eecs.umich.edu    }
2926254Sgblack@eecs.umich.edu    return 0;
2936254Sgblack@eecs.umich.edu}
2946254Sgblack@eecs.umich.edu
29512104Snathanael.premillieu@arm.comvoid
29613759Sgiacomo.gabrielli@arm.comArmStaticInst::printIntReg(std::ostream &os, RegIndex reg_idx,
29713759Sgiacomo.gabrielli@arm.com                           uint8_t opWidth) const
29812104Snathanael.premillieu@arm.com{
29913759Sgiacomo.gabrielli@arm.com    if (opWidth == 0)
30013759Sgiacomo.gabrielli@arm.com        opWidth = intWidth;
30112104Snathanael.premillieu@arm.com    if (aarch64) {
30212104Snathanael.premillieu@arm.com        if (reg_idx == INTREG_UREG0)
30312104Snathanael.premillieu@arm.com            ccprintf(os, "ureg0");
30412104Snathanael.premillieu@arm.com        else if (reg_idx == INTREG_SPX)
30513759Sgiacomo.gabrielli@arm.com            ccprintf(os, "%s%s", (opWidth == 32) ? "w" : "", "sp");
30612104Snathanael.premillieu@arm.com        else if (reg_idx == INTREG_X31)
30713759Sgiacomo.gabrielli@arm.com            ccprintf(os, "%szr", (opWidth == 32) ? "w" : "x");
30812104Snathanael.premillieu@arm.com        else
30913759Sgiacomo.gabrielli@arm.com            ccprintf(os, "%s%d", (opWidth == 32) ? "w" : "x", reg_idx);
31012104Snathanael.premillieu@arm.com    } else {
31112104Snathanael.premillieu@arm.com        switch (reg_idx) {
31212104Snathanael.premillieu@arm.com          case PCReg:
31312104Snathanael.premillieu@arm.com            ccprintf(os, "pc");
31412104Snathanael.premillieu@arm.com            break;
31512104Snathanael.premillieu@arm.com          case StackPointerReg:
31612104Snathanael.premillieu@arm.com            ccprintf(os, "sp");
31712104Snathanael.premillieu@arm.com            break;
31812104Snathanael.premillieu@arm.com          case FramePointerReg:
31912104Snathanael.premillieu@arm.com             ccprintf(os, "fp");
32012104Snathanael.premillieu@arm.com             break;
32112104Snathanael.premillieu@arm.com          case ReturnAddressReg:
32212104Snathanael.premillieu@arm.com             ccprintf(os, "lr");
32312104Snathanael.premillieu@arm.com             break;
32412104Snathanael.premillieu@arm.com          default:
32512104Snathanael.premillieu@arm.com             ccprintf(os, "r%d", reg_idx);
32612104Snathanael.premillieu@arm.com             break;
32712104Snathanael.premillieu@arm.com        }
32812104Snathanael.premillieu@arm.com    }
32912104Snathanael.premillieu@arm.com}
3306254Sgblack@eecs.umich.edu
33113367Syuetsu.kodama@riken.jpvoid ArmStaticInst::printPFflags(std::ostream &os, int flag) const
33213367Syuetsu.kodama@riken.jp{
33313367Syuetsu.kodama@riken.jp    const char *flagtoprfop[]= { "PLD", "PLI", "PST", "Reserved"};
33413367Syuetsu.kodama@riken.jp    const char *flagtotarget[] = { "L1", "L2", "L3", "Reserved"};
33513367Syuetsu.kodama@riken.jp    const char *flagtopolicy[] = { "KEEP", "STRM"};
33613367Syuetsu.kodama@riken.jp
33713367Syuetsu.kodama@riken.jp    ccprintf(os, "%s%s%s", flagtoprfop[(flag>>3)&3],
33813367Syuetsu.kodama@riken.jp             flagtotarget[(flag>>1)&3], flagtopolicy[flag&1]);
33913367Syuetsu.kodama@riken.jp}
34013367Syuetsu.kodama@riken.jp
3416254Sgblack@eecs.umich.eduvoid
34212104Snathanael.premillieu@arm.comArmStaticInst::printFloatReg(std::ostream &os, RegIndex reg_idx) const
3436253Sgblack@eecs.umich.edu{
34412104Snathanael.premillieu@arm.com    ccprintf(os, "f%d", reg_idx);
34512104Snathanael.premillieu@arm.com}
3469913Ssteve.reinhardt@amd.com
34712104Snathanael.premillieu@arm.comvoid
34813759Sgiacomo.gabrielli@arm.comArmStaticInst::printVecReg(std::ostream &os, RegIndex reg_idx,
34913759Sgiacomo.gabrielli@arm.com                           bool isSveVecReg) const
35012109SRekai.GonzalezAlberquilla@arm.com{
35113759Sgiacomo.gabrielli@arm.com    ccprintf(os, "%s%d", isSveVecReg ? "z" : "v", reg_idx);
35213759Sgiacomo.gabrielli@arm.com}
35313759Sgiacomo.gabrielli@arm.com
35413759Sgiacomo.gabrielli@arm.comvoid
35513759Sgiacomo.gabrielli@arm.comArmStaticInst::printVecPredReg(std::ostream &os, RegIndex reg_idx) const
35613759Sgiacomo.gabrielli@arm.com{
35713759Sgiacomo.gabrielli@arm.com    ccprintf(os, "p%d", reg_idx);
35812109SRekai.GonzalezAlberquilla@arm.com}
35912109SRekai.GonzalezAlberquilla@arm.com
36012109SRekai.GonzalezAlberquilla@arm.comvoid
36112104Snathanael.premillieu@arm.comArmStaticInst::printCCReg(std::ostream &os, RegIndex reg_idx) const
36212104Snathanael.premillieu@arm.com{
36312104Snathanael.premillieu@arm.com    ccprintf(os, "cc_%s", ArmISA::ccRegName[reg_idx]);
36412104Snathanael.premillieu@arm.com}
36512104Snathanael.premillieu@arm.com
36612104Snathanael.premillieu@arm.comvoid
36712104Snathanael.premillieu@arm.comArmStaticInst::printMiscReg(std::ostream &os, RegIndex reg_idx) const
36812104Snathanael.premillieu@arm.com{
36912104Snathanael.premillieu@arm.com    assert(reg_idx < NUM_MISCREGS);
37012104Snathanael.premillieu@arm.com    ccprintf(os, "%s", ArmISA::miscRegName[reg_idx]);
3716253Sgblack@eecs.umich.edu}
3726253Sgblack@eecs.umich.edu
3736262Sgblack@eecs.umich.eduvoid
3747148Sgblack@eecs.umich.eduArmStaticInst::printMnemonic(std::ostream &os,
3756262Sgblack@eecs.umich.edu                             const std::string &suffix,
37610037SARM gem5 Developers                             bool withPred,
37710037SARM gem5 Developers                             bool withCond64,
37810037SARM gem5 Developers                             ConditionCode cond64) const
3796262Sgblack@eecs.umich.edu{
3806262Sgblack@eecs.umich.edu    os << "  " << mnemonic;
38110037SARM gem5 Developers    if (withPred && !aarch64) {
38210037SARM gem5 Developers        printCondition(os, machInst.condCode);
3837122Sgblack@eecs.umich.edu        os << suffix;
38410037SARM gem5 Developers    } else if (withCond64) {
38510037SARM gem5 Developers        os << ".";
38610037SARM gem5 Developers        printCondition(os, cond64);
38710037SARM gem5 Developers        os << suffix;
38810037SARM gem5 Developers    }
38910037SARM gem5 Developers    if (machInst.bigThumb)
39010037SARM gem5 Developers        os << ".w";
39110037SARM gem5 Developers    os << "   ";
39210037SARM gem5 Developers}
39310037SARM gem5 Developers
39410037SARM gem5 Developersvoid
39510037SARM gem5 DevelopersArmStaticInst::printTarget(std::ostream &os, Addr target,
39610037SARM gem5 Developers                           const SymbolTable *symtab) const
39710037SARM gem5 Developers{
39810037SARM gem5 Developers    Addr symbolAddr;
39910037SARM gem5 Developers    std::string symbol;
40010037SARM gem5 Developers
40110037SARM gem5 Developers    if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) {
40210037SARM gem5 Developers        ccprintf(os, "<%s", symbol);
40310037SARM gem5 Developers        if (symbolAddr != target)
40410037SARM gem5 Developers            ccprintf(os, "+%d>", target - symbolAddr);
40510037SARM gem5 Developers        else
40610037SARM gem5 Developers            ccprintf(os, ">");
40710037SARM gem5 Developers    } else {
40810037SARM gem5 Developers        ccprintf(os, "%#x", target);
40910037SARM gem5 Developers    }
41010037SARM gem5 Developers}
41110037SARM gem5 Developers
41210037SARM gem5 Developersvoid
41310037SARM gem5 DevelopersArmStaticInst::printCondition(std::ostream &os,
41410037SARM gem5 Developers                              unsigned code,
41510037SARM gem5 Developers                              bool noImplicit) const
41610037SARM gem5 Developers{
41710037SARM gem5 Developers    switch (code) {
41810037SARM gem5 Developers      case COND_EQ:
41910037SARM gem5 Developers        os << "eq";
42010037SARM gem5 Developers        break;
42110037SARM gem5 Developers      case COND_NE:
42210037SARM gem5 Developers        os << "ne";
42310037SARM gem5 Developers        break;
42410037SARM gem5 Developers      case COND_CS:
42510037SARM gem5 Developers        os << "cs";
42610037SARM gem5 Developers        break;
42710037SARM gem5 Developers      case COND_CC:
42810037SARM gem5 Developers        os << "cc";
42910037SARM gem5 Developers        break;
43010037SARM gem5 Developers      case COND_MI:
43110037SARM gem5 Developers        os << "mi";
43210037SARM gem5 Developers        break;
43310037SARM gem5 Developers      case COND_PL:
43410037SARM gem5 Developers        os << "pl";
43510037SARM gem5 Developers        break;
43610037SARM gem5 Developers      case COND_VS:
43710037SARM gem5 Developers        os << "vs";
43810037SARM gem5 Developers        break;
43910037SARM gem5 Developers      case COND_VC:
44010037SARM gem5 Developers        os << "vc";
44110037SARM gem5 Developers        break;
44210037SARM gem5 Developers      case COND_HI:
44310037SARM gem5 Developers        os << "hi";
44410037SARM gem5 Developers        break;
44510037SARM gem5 Developers      case COND_LS:
44610037SARM gem5 Developers        os << "ls";
44710037SARM gem5 Developers        break;
44810037SARM gem5 Developers      case COND_GE:
44910037SARM gem5 Developers        os << "ge";
45010037SARM gem5 Developers        break;
45110037SARM gem5 Developers      case COND_LT:
45210037SARM gem5 Developers        os << "lt";
45310037SARM gem5 Developers        break;
45410037SARM gem5 Developers      case COND_GT:
45510037SARM gem5 Developers        os << "gt";
45610037SARM gem5 Developers        break;
45710037SARM gem5 Developers      case COND_LE:
45810037SARM gem5 Developers        os << "le";
45910037SARM gem5 Developers        break;
46010037SARM gem5 Developers      case COND_AL:
46110037SARM gem5 Developers        // This one is implicit.
46210037SARM gem5 Developers        if (noImplicit)
46310037SARM gem5 Developers            os << "al";
46410037SARM gem5 Developers        break;
46510037SARM gem5 Developers      case COND_UC:
46610037SARM gem5 Developers        // Unconditional.
46710037SARM gem5 Developers        if (noImplicit)
46810037SARM gem5 Developers            os << "uc";
46910037SARM gem5 Developers        break;
47010037SARM gem5 Developers      default:
47110037SARM gem5 Developers        panic("Unrecognized condition code %d.\n", code);
4726262Sgblack@eecs.umich.edu    }
4736262Sgblack@eecs.umich.edu}
4746262Sgblack@eecs.umich.edu
4756263Sgblack@eecs.umich.eduvoid
4767148Sgblack@eecs.umich.eduArmStaticInst::printMemSymbol(std::ostream &os,
4776263Sgblack@eecs.umich.edu                              const SymbolTable *symtab,
4786263Sgblack@eecs.umich.edu                              const std::string &prefix,
4796263Sgblack@eecs.umich.edu                              const Addr addr,
4806263Sgblack@eecs.umich.edu                              const std::string &suffix) const
4816263Sgblack@eecs.umich.edu{
4826263Sgblack@eecs.umich.edu    Addr symbolAddr;
4836263Sgblack@eecs.umich.edu    std::string symbol;
4846263Sgblack@eecs.umich.edu    if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
4856263Sgblack@eecs.umich.edu        ccprintf(os, "%s%s", prefix, symbol);
4866263Sgblack@eecs.umich.edu        if (symbolAddr != addr)
4876263Sgblack@eecs.umich.edu            ccprintf(os, "+%d", addr - symbolAddr);
4886263Sgblack@eecs.umich.edu        ccprintf(os, suffix);
4896263Sgblack@eecs.umich.edu    }
4906263Sgblack@eecs.umich.edu}
4916263Sgblack@eecs.umich.edu
4926264Sgblack@eecs.umich.eduvoid
4937148Sgblack@eecs.umich.eduArmStaticInst::printShiftOperand(std::ostream &os,
4947142Sgblack@eecs.umich.edu                                     IntRegIndex rm,
4957142Sgblack@eecs.umich.edu                                     bool immShift,
4967142Sgblack@eecs.umich.edu                                     uint32_t shiftAmt,
4977142Sgblack@eecs.umich.edu                                     IntRegIndex rs,
4987142Sgblack@eecs.umich.edu                                     ArmShiftType type) const
4996264Sgblack@eecs.umich.edu{
5007142Sgblack@eecs.umich.edu    bool firstOp = false;
5016264Sgblack@eecs.umich.edu
5027142Sgblack@eecs.umich.edu    if (rm != INTREG_ZERO) {
50312104Snathanael.premillieu@arm.com        printIntReg(os, rm);
5047142Sgblack@eecs.umich.edu    }
5057142Sgblack@eecs.umich.edu
5066306Sgblack@eecs.umich.edu    bool done = false;
5076264Sgblack@eecs.umich.edu
5086306Sgblack@eecs.umich.edu    if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
5096306Sgblack@eecs.umich.edu        shiftAmt = 32;
5106264Sgblack@eecs.umich.edu
5116306Sgblack@eecs.umich.edu    switch (type) {
5126306Sgblack@eecs.umich.edu      case LSL:
5136306Sgblack@eecs.umich.edu        if (immShift && shiftAmt == 0) {
5146306Sgblack@eecs.umich.edu            done = true;
5156264Sgblack@eecs.umich.edu            break;
5166306Sgblack@eecs.umich.edu        }
5177142Sgblack@eecs.umich.edu        if (!firstOp)
5187142Sgblack@eecs.umich.edu            os << ", ";
5197142Sgblack@eecs.umich.edu        os << "LSL";
5206306Sgblack@eecs.umich.edu        break;
5216306Sgblack@eecs.umich.edu      case LSR:
5227142Sgblack@eecs.umich.edu        if (!firstOp)
5237142Sgblack@eecs.umich.edu            os << ", ";
5247142Sgblack@eecs.umich.edu        os << "LSR";
5256306Sgblack@eecs.umich.edu        break;
5266306Sgblack@eecs.umich.edu      case ASR:
5277142Sgblack@eecs.umich.edu        if (!firstOp)
5287142Sgblack@eecs.umich.edu            os << ", ";
5297142Sgblack@eecs.umich.edu        os << "ASR";
5306306Sgblack@eecs.umich.edu        break;
5316306Sgblack@eecs.umich.edu      case ROR:
5326306Sgblack@eecs.umich.edu        if (immShift && shiftAmt == 0) {
5337142Sgblack@eecs.umich.edu            if (!firstOp)
5347142Sgblack@eecs.umich.edu                os << ", ";
5357142Sgblack@eecs.umich.edu            os << "RRX";
5366306Sgblack@eecs.umich.edu            done = true;
5376264Sgblack@eecs.umich.edu            break;
5386264Sgblack@eecs.umich.edu        }
5397142Sgblack@eecs.umich.edu        if (!firstOp)
5407142Sgblack@eecs.umich.edu            os << ", ";
5417142Sgblack@eecs.umich.edu        os << "ROR";
5426306Sgblack@eecs.umich.edu        break;
5436306Sgblack@eecs.umich.edu      default:
5446306Sgblack@eecs.umich.edu        panic("Tried to disassemble unrecognized shift type.\n");
5456306Sgblack@eecs.umich.edu    }
5466306Sgblack@eecs.umich.edu    if (!done) {
5477142Sgblack@eecs.umich.edu        if (!firstOp)
5487142Sgblack@eecs.umich.edu            os << " ";
5496306Sgblack@eecs.umich.edu        if (immShift)
5506306Sgblack@eecs.umich.edu            os << "#" << shiftAmt;
5516306Sgblack@eecs.umich.edu        else
55212104Snathanael.premillieu@arm.com            printIntReg(os, rs);
5536264Sgblack@eecs.umich.edu    }
5546264Sgblack@eecs.umich.edu}
5556264Sgblack@eecs.umich.edu
5566264Sgblack@eecs.umich.eduvoid
55710037SARM gem5 DevelopersArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os,
55810037SARM gem5 Developers                                  IntRegIndex rm, ArmExtendType type,
55910037SARM gem5 Developers                                  int64_t shiftAmt) const
56010037SARM gem5 Developers{
56110037SARM gem5 Developers    if (!firstOperand)
56210037SARM gem5 Developers        ccprintf(os, ", ");
56312104Snathanael.premillieu@arm.com    printIntReg(os, rm);
56410037SARM gem5 Developers    if (type == UXTX && shiftAmt == 0)
56510037SARM gem5 Developers        return;
56610037SARM gem5 Developers    switch (type) {
56710037SARM gem5 Developers      case UXTB: ccprintf(os, ", UXTB");
56810037SARM gem5 Developers        break;
56910037SARM gem5 Developers      case UXTH: ccprintf(os, ", UXTH");
57010037SARM gem5 Developers        break;
57110037SARM gem5 Developers      case UXTW: ccprintf(os, ", UXTW");
57210037SARM gem5 Developers        break;
57310037SARM gem5 Developers      case UXTX: ccprintf(os, ", LSL");
57410037SARM gem5 Developers        break;
57510037SARM gem5 Developers      case SXTB: ccprintf(os, ", SXTB");
57610037SARM gem5 Developers        break;
57710037SARM gem5 Developers      case SXTH: ccprintf(os, ", SXTH");
57810037SARM gem5 Developers        break;
57910037SARM gem5 Developers      case SXTW: ccprintf(os, ", SXTW");
58010037SARM gem5 Developers        break;
58110037SARM gem5 Developers      case SXTX: ccprintf(os, ", SXTW");
58210037SARM gem5 Developers        break;
58310037SARM gem5 Developers    }
58410037SARM gem5 Developers    if (type == UXTX || shiftAmt)
58510037SARM gem5 Developers        ccprintf(os, " #%d", shiftAmt);
58610037SARM gem5 Developers}
58710037SARM gem5 Developers
58810037SARM gem5 Developersvoid
5897148Sgblack@eecs.umich.eduArmStaticInst::printDataInst(std::ostream &os, bool withImm,
5907142Sgblack@eecs.umich.edu        bool immShift, bool s, IntRegIndex rd, IntRegIndex rn,
5917142Sgblack@eecs.umich.edu        IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt,
59211371Snathanael.premillieu@arm.com        ArmShiftType type, uint64_t imm) const
5936264Sgblack@eecs.umich.edu{
5947142Sgblack@eecs.umich.edu    printMnemonic(os, s ? "s" : "");
5956264Sgblack@eecs.umich.edu    bool firstOp = true;
5966264Sgblack@eecs.umich.edu
5976264Sgblack@eecs.umich.edu    // Destination
5987142Sgblack@eecs.umich.edu    if (rd != INTREG_ZERO) {
5996264Sgblack@eecs.umich.edu        firstOp = false;
60012104Snathanael.premillieu@arm.com        printIntReg(os, rd);
6016264Sgblack@eecs.umich.edu    }
6026264Sgblack@eecs.umich.edu
6036264Sgblack@eecs.umich.edu    // Source 1.
6047142Sgblack@eecs.umich.edu    if (rn != INTREG_ZERO) {
6056264Sgblack@eecs.umich.edu        if (!firstOp)
6066264Sgblack@eecs.umich.edu            os << ", ";
6076264Sgblack@eecs.umich.edu        firstOp = false;
60812104Snathanael.premillieu@arm.com        printIntReg(os, rn);
6096264Sgblack@eecs.umich.edu    }
6106264Sgblack@eecs.umich.edu
6116264Sgblack@eecs.umich.edu    if (!firstOp)
6126264Sgblack@eecs.umich.edu        os << ", ";
6136306Sgblack@eecs.umich.edu    if (withImm) {
61411371Snathanael.premillieu@arm.com        ccprintf(os, "#%ld", imm);
6156306Sgblack@eecs.umich.edu    } else {
6167142Sgblack@eecs.umich.edu        printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
6176306Sgblack@eecs.umich.edu    }
6186264Sgblack@eecs.umich.edu}
6196264Sgblack@eecs.umich.edu
6206254Sgblack@eecs.umich.edustd::string
6217148Sgblack@eecs.umich.eduArmStaticInst::generateDisassembly(Addr pc,
6226254Sgblack@eecs.umich.edu                                   const SymbolTable *symtab) const
6236253Sgblack@eecs.umich.edu{
6246253Sgblack@eecs.umich.edu    std::stringstream ss;
6256262Sgblack@eecs.umich.edu    printMnemonic(ss);
6266253Sgblack@eecs.umich.edu    return ss.str();
6276253Sgblack@eecs.umich.edu}
62811513Sandreas.sandberg@arm.com
62912789Sgiacomo.travaglini@arm.comFault
63012789Sgiacomo.travaglini@arm.comArmStaticInst::softwareBreakpoint32(ExecContext *xc, uint16_t imm) const
63112789Sgiacomo.travaglini@arm.com{
63212789Sgiacomo.travaglini@arm.com    const auto tc = xc->tcBase();
63312789Sgiacomo.travaglini@arm.com    const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
63412789Sgiacomo.travaglini@arm.com    const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
63512789Sgiacomo.travaglini@arm.com    if ((ArmSystem::haveEL(tc, EL2) && !inSecureState(tc) &&
63612789Sgiacomo.travaglini@arm.com         !ELIs32(tc, EL2) && (hcr.tge == 1 || mdcr.tde == 1)) ||
63712789Sgiacomo.travaglini@arm.com         !ELIs32(tc, EL1)) {
63812789Sgiacomo.travaglini@arm.com        // Route to AArch64 Software Breakpoint
63912789Sgiacomo.travaglini@arm.com        return std::make_shared<SoftwareBreakpoint>(machInst, imm);
64012789Sgiacomo.travaglini@arm.com    } else {
64112789Sgiacomo.travaglini@arm.com        // Execute AArch32 Software Breakpoint
64212789Sgiacomo.travaglini@arm.com        return std::make_shared<PrefetchAbort>(readPC(xc),
64312789Sgiacomo.travaglini@arm.com                                               ArmFault::DebugEvent);
64412789Sgiacomo.travaglini@arm.com    }
64512789Sgiacomo.travaglini@arm.com}
64611513Sandreas.sandberg@arm.com
64711513Sandreas.sandberg@arm.comFault
64811513Sandreas.sandberg@arm.comArmStaticInst::advSIMDFPAccessTrap64(ExceptionLevel el) const
64911513Sandreas.sandberg@arm.com{
65011513Sandreas.sandberg@arm.com    switch (el) {
65111513Sandreas.sandberg@arm.com      case EL1:
65211513Sandreas.sandberg@arm.com        return std::make_shared<SupervisorTrap>(machInst, 0x1E00000,
65311513Sandreas.sandberg@arm.com                                                EC_TRAPPED_SIMD_FP);
65411513Sandreas.sandberg@arm.com      case EL2:
65511513Sandreas.sandberg@arm.com        return std::make_shared<HypervisorTrap>(machInst, 0x1E00000,
65611513Sandreas.sandberg@arm.com                                                EC_TRAPPED_SIMD_FP);
65711513Sandreas.sandberg@arm.com      case EL3:
65811513Sandreas.sandberg@arm.com        return std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000,
65911513Sandreas.sandberg@arm.com                                                   EC_TRAPPED_SIMD_FP);
66011513Sandreas.sandberg@arm.com
66111513Sandreas.sandberg@arm.com      default:
66211513Sandreas.sandberg@arm.com        panic("Illegal EL in advSIMDFPAccessTrap64\n");
66311513Sandreas.sandberg@arm.com    }
6646253Sgblack@eecs.umich.edu}
66511513Sandreas.sandberg@arm.com
66611513Sandreas.sandberg@arm.com
66711513Sandreas.sandberg@arm.comFault
66811513Sandreas.sandberg@arm.comArmStaticInst::checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const
66911513Sandreas.sandberg@arm.com{
67012520Schuan.zhu@arm.com    if (ArmSystem::haveVirtualization(tc) && !inSecureState(tc)) {
67111513Sandreas.sandberg@arm.com        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL2);
67211513Sandreas.sandberg@arm.com        if (cptrEnCheck.tfp)
67311513Sandreas.sandberg@arm.com            return advSIMDFPAccessTrap64(EL2);
67411513Sandreas.sandberg@arm.com    }
67511513Sandreas.sandberg@arm.com
67611513Sandreas.sandberg@arm.com    if (ArmSystem::haveSecurity(tc)) {
67711513Sandreas.sandberg@arm.com        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3);
67811513Sandreas.sandberg@arm.com        if (cptrEnCheck.tfp)
67911513Sandreas.sandberg@arm.com            return advSIMDFPAccessTrap64(EL3);
68011513Sandreas.sandberg@arm.com    }
68111513Sandreas.sandberg@arm.com
68211513Sandreas.sandberg@arm.com    return NoFault;
68311513Sandreas.sandberg@arm.com}
68411513Sandreas.sandberg@arm.com
68511513Sandreas.sandberg@arm.comFault
68611513Sandreas.sandberg@arm.comArmStaticInst::checkFPAdvSIMDEnabled64(ThreadContext *tc,
68711513Sandreas.sandberg@arm.com                                       CPSR cpsr, CPACR cpacr) const
68811513Sandreas.sandberg@arm.com{
68914171Sgiacomo.travaglini@arm.com    const ExceptionLevel el = currEL(tc);
69011513Sandreas.sandberg@arm.com    if ((el == EL0 && cpacr.fpen != 0x3) ||
69111513Sandreas.sandberg@arm.com        (el == EL1 && !(cpacr.fpen & 0x1)))
69211513Sandreas.sandberg@arm.com        return advSIMDFPAccessTrap64(EL1);
69311513Sandreas.sandberg@arm.com
69411513Sandreas.sandberg@arm.com    return checkFPAdvSIMDTrap64(tc, cpsr);
69511513Sandreas.sandberg@arm.com}
69611513Sandreas.sandberg@arm.com
69711513Sandreas.sandberg@arm.comFault
69811513Sandreas.sandberg@arm.comArmStaticInst::checkAdvSIMDOrFPEnabled32(ThreadContext *tc,
69911513Sandreas.sandberg@arm.com                                         CPSR cpsr, CPACR cpacr,
70011513Sandreas.sandberg@arm.com                                         NSACR nsacr, FPEXC fpexc,
70111513Sandreas.sandberg@arm.com                                         bool fpexc_check, bool advsimd) const
70211513Sandreas.sandberg@arm.com{
70311513Sandreas.sandberg@arm.com    const bool have_virtualization = ArmSystem::haveVirtualization(tc);
70411513Sandreas.sandberg@arm.com    const bool have_security = ArmSystem::haveSecurity(tc);
70511513Sandreas.sandberg@arm.com    const bool is_secure = inSecureState(tc);
70614172Sgiacomo.travaglini@arm.com    const ExceptionLevel cur_el = currEL(tc);
70711513Sandreas.sandberg@arm.com
70811513Sandreas.sandberg@arm.com    if (cur_el == EL0 && ELIs64(tc, EL1))
70911513Sandreas.sandberg@arm.com        return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr);
71011513Sandreas.sandberg@arm.com
71111513Sandreas.sandberg@arm.com    uint8_t cpacr_cp10 = cpacr.cp10;
71211513Sandreas.sandberg@arm.com    bool cpacr_asedis = cpacr.asedis;
71311513Sandreas.sandberg@arm.com
71411513Sandreas.sandberg@arm.com    if (have_security && !ELIs64(tc, EL3) && !is_secure) {
71511513Sandreas.sandberg@arm.com        if (nsacr.nsasedis)
71611513Sandreas.sandberg@arm.com            cpacr_asedis = true;
71711513Sandreas.sandberg@arm.com        if (nsacr.cp10 == 0)
71811513Sandreas.sandberg@arm.com            cpacr_cp10 = 0;
71911513Sandreas.sandberg@arm.com    }
72011513Sandreas.sandberg@arm.com
72111513Sandreas.sandberg@arm.com    if (cur_el != EL2) {
72211513Sandreas.sandberg@arm.com        if (advsimd && cpacr_asedis)
72311513Sandreas.sandberg@arm.com            return disabledFault();
72411513Sandreas.sandberg@arm.com
72511513Sandreas.sandberg@arm.com        if ((cur_el == EL0 && cpacr_cp10 != 0x3) ||
72611513Sandreas.sandberg@arm.com            (cur_el != EL0 && !(cpacr_cp10 & 0x1)))
72711513Sandreas.sandberg@arm.com            return disabledFault();
72811513Sandreas.sandberg@arm.com    }
72911513Sandreas.sandberg@arm.com
73011513Sandreas.sandberg@arm.com    if (fpexc_check && !fpexc.en)
73111513Sandreas.sandberg@arm.com        return disabledFault();
73211513Sandreas.sandberg@arm.com
73311513Sandreas.sandberg@arm.com    // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap --
73411513Sandreas.sandberg@arm.com
73511513Sandreas.sandberg@arm.com    if (have_virtualization && !is_secure && ELIs64(tc, EL2))
73611513Sandreas.sandberg@arm.com        return checkFPAdvSIMDTrap64(tc, cpsr);
73711513Sandreas.sandberg@arm.com
73811513Sandreas.sandberg@arm.com    if (have_virtualization && !is_secure) {
73911513Sandreas.sandberg@arm.com        HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR);
74011513Sandreas.sandberg@arm.com        bool hcptr_cp10 = hcptr.tcp10;
74111513Sandreas.sandberg@arm.com        bool hcptr_tase = hcptr.tase;
74211513Sandreas.sandberg@arm.com
74311513Sandreas.sandberg@arm.com        if (have_security && !ELIs64(tc, EL3) && !is_secure) {
74411513Sandreas.sandberg@arm.com            if (nsacr.nsasedis)
74511513Sandreas.sandberg@arm.com                hcptr_tase = true;
74611513Sandreas.sandberg@arm.com            if (nsacr.cp10)
74711513Sandreas.sandberg@arm.com                hcptr_cp10 = true;
74811513Sandreas.sandberg@arm.com        }
74911513Sandreas.sandberg@arm.com
75011513Sandreas.sandberg@arm.com        if ((advsimd && hcptr_tase) || hcptr_cp10) {
75111513Sandreas.sandberg@arm.com            const uint32_t iss = advsimd ? (1 << 5) : 0xA;
75211513Sandreas.sandberg@arm.com            if (cur_el == EL2) {
75311513Sandreas.sandberg@arm.com                return std::make_shared<UndefinedInstruction>(
75411513Sandreas.sandberg@arm.com                    machInst, iss,
75511513Sandreas.sandberg@arm.com                    EC_TRAPPED_HCPTR, mnemonic);
75611513Sandreas.sandberg@arm.com            } else {
75711513Sandreas.sandberg@arm.com                return std::make_shared<HypervisorTrap>(
75811513Sandreas.sandberg@arm.com                    machInst, iss,
75911513Sandreas.sandberg@arm.com                    EC_TRAPPED_HCPTR);
76011513Sandreas.sandberg@arm.com            }
76111513Sandreas.sandberg@arm.com
76211513Sandreas.sandberg@arm.com        }
76311513Sandreas.sandberg@arm.com    }
76411513Sandreas.sandberg@arm.com
76511513Sandreas.sandberg@arm.com    if (have_security && ELIs64(tc, EL3)) {
76611513Sandreas.sandberg@arm.com        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3);
76711513Sandreas.sandberg@arm.com        if (cptrEnCheck.tfp)
76811513Sandreas.sandberg@arm.com            return advSIMDFPAccessTrap64(EL3);
76911513Sandreas.sandberg@arm.com    }
77011513Sandreas.sandberg@arm.com
77111513Sandreas.sandberg@arm.com    return NoFault;
77211513Sandreas.sandberg@arm.com}
77311513Sandreas.sandberg@arm.com
77412403Sgiacomo.travaglini@arm.cominline bool
77512403Sgiacomo.travaglini@arm.comArmStaticInst::isWFxTrapping(ThreadContext *tc,
77612403Sgiacomo.travaglini@arm.com                             ExceptionLevel tgtEl,
77712403Sgiacomo.travaglini@arm.com                             bool isWfe) const
77812403Sgiacomo.travaglini@arm.com{
77912403Sgiacomo.travaglini@arm.com    bool trap = false;
78012403Sgiacomo.travaglini@arm.com    SCTLR sctlr = ((SCTLR)tc->readMiscReg(MISCREG_SCTLR_EL1));
78112403Sgiacomo.travaglini@arm.com    HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
78212403Sgiacomo.travaglini@arm.com    SCR scr = ((SCR)tc->readMiscReg(MISCREG_SCR_EL3));
78312403Sgiacomo.travaglini@arm.com
78412403Sgiacomo.travaglini@arm.com    switch (tgtEl) {
78512403Sgiacomo.travaglini@arm.com      case EL1:
78612403Sgiacomo.travaglini@arm.com        trap = isWfe? !sctlr.ntwe : !sctlr.ntwi;
78712403Sgiacomo.travaglini@arm.com        break;
78812403Sgiacomo.travaglini@arm.com      case EL2:
78912403Sgiacomo.travaglini@arm.com        trap = isWfe? hcr.twe : hcr.twi;
79012403Sgiacomo.travaglini@arm.com        break;
79112403Sgiacomo.travaglini@arm.com      case EL3:
79212403Sgiacomo.travaglini@arm.com        trap = isWfe? scr.twe : scr.twi;
79312403Sgiacomo.travaglini@arm.com        break;
79412403Sgiacomo.travaglini@arm.com      default:
79512403Sgiacomo.travaglini@arm.com        break;
79612403Sgiacomo.travaglini@arm.com    }
79712403Sgiacomo.travaglini@arm.com
79812403Sgiacomo.travaglini@arm.com    return trap;
79912403Sgiacomo.travaglini@arm.com}
80012403Sgiacomo.travaglini@arm.com
80112403Sgiacomo.travaglini@arm.comFault
80212403Sgiacomo.travaglini@arm.comArmStaticInst::checkForWFxTrap32(ThreadContext *tc,
80312403Sgiacomo.travaglini@arm.com                                 ExceptionLevel targetEL,
80412403Sgiacomo.travaglini@arm.com                                 bool isWfe) const
80512403Sgiacomo.travaglini@arm.com{
80612403Sgiacomo.travaglini@arm.com    // Check if target exception level is implemented.
80712403Sgiacomo.travaglini@arm.com    assert(ArmSystem::haveEL(tc, targetEL));
80812403Sgiacomo.travaglini@arm.com
80912403Sgiacomo.travaglini@arm.com    // Check for routing to AArch64: this happens if the
81012403Sgiacomo.travaglini@arm.com    // target exception level (where the trap will be handled)
81112403Sgiacomo.travaglini@arm.com    // is using aarch64
81212403Sgiacomo.travaglini@arm.com    if (ELIs64(tc, targetEL)) {
81312403Sgiacomo.travaglini@arm.com        return checkForWFxTrap64(tc, targetEL, isWfe);
81412403Sgiacomo.travaglini@arm.com    }
81512403Sgiacomo.travaglini@arm.com
81612403Sgiacomo.travaglini@arm.com    // Check if processor needs to trap at selected exception level
81712403Sgiacomo.travaglini@arm.com    bool trap = isWFxTrapping(tc, targetEL, isWfe);
81812403Sgiacomo.travaglini@arm.com
81912403Sgiacomo.travaglini@arm.com    if (trap) {
82012403Sgiacomo.travaglini@arm.com        uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */
82112403Sgiacomo.travaglini@arm.com                              0x1E00000;  /* WFI Instruction syndrome */
82212403Sgiacomo.travaglini@arm.com        switch (targetEL) {
82312403Sgiacomo.travaglini@arm.com          case EL1:
82412403Sgiacomo.travaglini@arm.com            return std::make_shared<UndefinedInstruction>(
82512403Sgiacomo.travaglini@arm.com                machInst, iss,
82612403Sgiacomo.travaglini@arm.com                EC_TRAPPED_WFI_WFE, mnemonic);
82712403Sgiacomo.travaglini@arm.com          case EL2:
82812403Sgiacomo.travaglini@arm.com            return std::make_shared<HypervisorTrap>(machInst, iss,
82912403Sgiacomo.travaglini@arm.com                                                    EC_TRAPPED_WFI_WFE);
83012403Sgiacomo.travaglini@arm.com          case EL3:
83112403Sgiacomo.travaglini@arm.com            return std::make_shared<SecureMonitorTrap>(machInst, iss,
83212403Sgiacomo.travaglini@arm.com                                                       EC_TRAPPED_WFI_WFE);
83312403Sgiacomo.travaglini@arm.com          default:
83412403Sgiacomo.travaglini@arm.com            panic("Unrecognized Exception Level: %d\n", targetEL);
83512403Sgiacomo.travaglini@arm.com        }
83612403Sgiacomo.travaglini@arm.com    }
83712403Sgiacomo.travaglini@arm.com
83812403Sgiacomo.travaglini@arm.com    return NoFault;
83912403Sgiacomo.travaglini@arm.com}
84012403Sgiacomo.travaglini@arm.com
84112403Sgiacomo.travaglini@arm.comFault
84212403Sgiacomo.travaglini@arm.comArmStaticInst::checkForWFxTrap64(ThreadContext *tc,
84312403Sgiacomo.travaglini@arm.com                                 ExceptionLevel targetEL,
84412403Sgiacomo.travaglini@arm.com                                 bool isWfe) const
84512403Sgiacomo.travaglini@arm.com{
84612403Sgiacomo.travaglini@arm.com    // Check if target exception level is implemented.
84712403Sgiacomo.travaglini@arm.com    assert(ArmSystem::haveEL(tc, targetEL));
84812403Sgiacomo.travaglini@arm.com
84912403Sgiacomo.travaglini@arm.com    // Check if processor needs to trap at selected exception level
85012403Sgiacomo.travaglini@arm.com    bool trap = isWFxTrapping(tc, targetEL, isWfe);
85112403Sgiacomo.travaglini@arm.com
85212403Sgiacomo.travaglini@arm.com    if (trap) {
85312403Sgiacomo.travaglini@arm.com        uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */
85412403Sgiacomo.travaglini@arm.com                              0x1E00000;  /* WFI Instruction syndrome */
85512403Sgiacomo.travaglini@arm.com        switch (targetEL) {
85612403Sgiacomo.travaglini@arm.com          case EL1:
85712403Sgiacomo.travaglini@arm.com            return std::make_shared<SupervisorTrap>(machInst, iss,
85812403Sgiacomo.travaglini@arm.com                                                    EC_TRAPPED_WFI_WFE);
85912403Sgiacomo.travaglini@arm.com          case EL2:
86012403Sgiacomo.travaglini@arm.com            return std::make_shared<HypervisorTrap>(machInst, iss,
86112403Sgiacomo.travaglini@arm.com                                                    EC_TRAPPED_WFI_WFE);
86212403Sgiacomo.travaglini@arm.com          case EL3:
86312403Sgiacomo.travaglini@arm.com            return std::make_shared<SecureMonitorTrap>(machInst, iss,
86412403Sgiacomo.travaglini@arm.com                                                       EC_TRAPPED_WFI_WFE);
86512403Sgiacomo.travaglini@arm.com          default:
86612403Sgiacomo.travaglini@arm.com            panic("Unrecognized Exception Level: %d\n", targetEL);
86712403Sgiacomo.travaglini@arm.com        }
86812403Sgiacomo.travaglini@arm.com    }
86912403Sgiacomo.travaglini@arm.com
87012403Sgiacomo.travaglini@arm.com    return NoFault;
87112403Sgiacomo.travaglini@arm.com}
87212403Sgiacomo.travaglini@arm.com
87312403Sgiacomo.travaglini@arm.comFault
87412403Sgiacomo.travaglini@arm.comArmStaticInst::trapWFx(ThreadContext *tc,
87512403Sgiacomo.travaglini@arm.com                       CPSR cpsr, SCR scr,
87612403Sgiacomo.travaglini@arm.com                       bool isWfe) const
87712403Sgiacomo.travaglini@arm.com{
87812403Sgiacomo.travaglini@arm.com    Fault fault = NoFault;
87914171Sgiacomo.travaglini@arm.com    ExceptionLevel curr_el = currEL(tc);
88014171Sgiacomo.travaglini@arm.com
88114171Sgiacomo.travaglini@arm.com    if (curr_el == EL0) {
88212403Sgiacomo.travaglini@arm.com        fault = checkForWFxTrap32(tc, EL1, isWfe);
88312403Sgiacomo.travaglini@arm.com    }
88412403Sgiacomo.travaglini@arm.com
88512403Sgiacomo.travaglini@arm.com    if ((fault == NoFault) &&
88612403Sgiacomo.travaglini@arm.com        ArmSystem::haveEL(tc, EL2) && !inSecureState(scr, cpsr) &&
88714171Sgiacomo.travaglini@arm.com        ((curr_el == EL0) || (curr_el == EL1))) {
88812403Sgiacomo.travaglini@arm.com
88912403Sgiacomo.travaglini@arm.com        fault = checkForWFxTrap32(tc, EL2, isWfe);
89012403Sgiacomo.travaglini@arm.com    }
89112403Sgiacomo.travaglini@arm.com
89212403Sgiacomo.travaglini@arm.com    if ((fault == NoFault) &&
89314171Sgiacomo.travaglini@arm.com        ArmSystem::haveEL(tc, EL3) && curr_el != EL3) {
89412403Sgiacomo.travaglini@arm.com        fault = checkForWFxTrap32(tc, EL3, isWfe);
89512403Sgiacomo.travaglini@arm.com    }
89612403Sgiacomo.travaglini@arm.com
89712403Sgiacomo.travaglini@arm.com    return fault;
89812403Sgiacomo.travaglini@arm.com}
89911513Sandreas.sandberg@arm.com
90012498Sgiacomo.travaglini@arm.comFault
90112498Sgiacomo.travaglini@arm.comArmStaticInst::checkSETENDEnabled(ThreadContext *tc, CPSR cpsr) const
90212498Sgiacomo.travaglini@arm.com{
90312498Sgiacomo.travaglini@arm.com    bool setend_disabled(false);
90414171Sgiacomo.travaglini@arm.com    ExceptionLevel pstate_el = currEL(tc);
90512498Sgiacomo.travaglini@arm.com
90614171Sgiacomo.travaglini@arm.com    if (pstate_el == EL2) {
90712498Sgiacomo.travaglini@arm.com       setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(MISCREG_HSCTLR)).sed;
90812498Sgiacomo.travaglini@arm.com    } else {
90912498Sgiacomo.travaglini@arm.com        // Please note: in the armarm pseudocode there is a distinction
91012498Sgiacomo.travaglini@arm.com        // whether EL1 is aarch32 or aarch64:
91112498Sgiacomo.travaglini@arm.com        // if ELUsingAArch32(EL1) then SCTLR.SED else SCTLR[].SED;
91212498Sgiacomo.travaglini@arm.com        // Considering that SETEND is aarch32 only, ELUsingAArch32(EL1)
91312498Sgiacomo.travaglini@arm.com        // will always be true (hence using SCTLR.SED) except for
91412498Sgiacomo.travaglini@arm.com        // instruction executed at EL0, and with an AArch64 EL1.
91512498Sgiacomo.travaglini@arm.com        // In this case SCTLR_EL1 will be used. In gem5 the register is
91612498Sgiacomo.travaglini@arm.com        // mapped to SCTLR_ns. We can safely use SCTLR and choose the
91712498Sgiacomo.travaglini@arm.com        // appropriate bank version.
91812498Sgiacomo.travaglini@arm.com
91912498Sgiacomo.travaglini@arm.com        // Get the index of the banked version of SCTLR:
92012498Sgiacomo.travaglini@arm.com        // SCTLR_s or SCTLR_ns.
92112499Sgiacomo.travaglini@arm.com        auto banked_sctlr = snsBankedIndex(
92212498Sgiacomo.travaglini@arm.com            MISCREG_SCTLR, tc, !inSecureState(tc));
92312498Sgiacomo.travaglini@arm.com
92412498Sgiacomo.travaglini@arm.com        // SCTLR.SED bit is enabling/disabling the ue of SETEND instruction.
92512498Sgiacomo.travaglini@arm.com        setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(banked_sctlr)).sed;
92612498Sgiacomo.travaglini@arm.com    }
92712498Sgiacomo.travaglini@arm.com
92814171Sgiacomo.travaglini@arm.com    return setend_disabled ? undefinedFault32(tc, pstate_el) :
92912498Sgiacomo.travaglini@arm.com                             NoFault;
93012498Sgiacomo.travaglini@arm.com}
93112498Sgiacomo.travaglini@arm.com
93212498Sgiacomo.travaglini@arm.comFault
93312498Sgiacomo.travaglini@arm.comArmStaticInst::undefinedFault32(ThreadContext *tc,
93412498Sgiacomo.travaglini@arm.com                                ExceptionLevel pstateEL) const
93512498Sgiacomo.travaglini@arm.com{
93612498Sgiacomo.travaglini@arm.com    // Even if we are running in aarch32, the fault might be dealt with in
93712498Sgiacomo.travaglini@arm.com    // aarch64 ISA.
93812498Sgiacomo.travaglini@arm.com    if (generalExceptionsToAArch64(tc, pstateEL)) {
93912498Sgiacomo.travaglini@arm.com        return undefinedFault64(tc, pstateEL);
94012498Sgiacomo.travaglini@arm.com    } else {
94112498Sgiacomo.travaglini@arm.com        // Please note: according to the ARM ARM pseudocode we should handle
94212498Sgiacomo.travaglini@arm.com        // the case when EL2 is aarch64 and HCR.TGE is 1 as well.
94312498Sgiacomo.travaglini@arm.com        // However this case is already handled by the routeToHyp method in
94412498Sgiacomo.travaglini@arm.com        // ArmFault class.
94512498Sgiacomo.travaglini@arm.com        return std::make_shared<UndefinedInstruction>(
94612498Sgiacomo.travaglini@arm.com            machInst, 0,
94712498Sgiacomo.travaglini@arm.com            EC_UNKNOWN, mnemonic);
94812498Sgiacomo.travaglini@arm.com    }
94912498Sgiacomo.travaglini@arm.com}
95012498Sgiacomo.travaglini@arm.com
95112498Sgiacomo.travaglini@arm.comFault
95212498Sgiacomo.travaglini@arm.comArmStaticInst::undefinedFault64(ThreadContext *tc,
95312498Sgiacomo.travaglini@arm.com                                ExceptionLevel pstateEL) const
95412498Sgiacomo.travaglini@arm.com{
95512498Sgiacomo.travaglini@arm.com    switch (pstateEL) {
95612498Sgiacomo.travaglini@arm.com      case EL0:
95712498Sgiacomo.travaglini@arm.com      case EL1:
95812498Sgiacomo.travaglini@arm.com        return std::make_shared<SupervisorTrap>(machInst, 0, EC_UNKNOWN);
95912498Sgiacomo.travaglini@arm.com      case EL2:
96012498Sgiacomo.travaglini@arm.com        return std::make_shared<HypervisorTrap>(machInst, 0, EC_UNKNOWN);
96112498Sgiacomo.travaglini@arm.com      case EL3:
96212498Sgiacomo.travaglini@arm.com        return std::make_shared<SecureMonitorTrap>(machInst, 0, EC_UNKNOWN);
96312498Sgiacomo.travaglini@arm.com      default:
96412498Sgiacomo.travaglini@arm.com        panic("Unrecognized Exception Level: %d\n", pstateEL);
96512498Sgiacomo.travaglini@arm.com        break;
96612498Sgiacomo.travaglini@arm.com    }
96712498Sgiacomo.travaglini@arm.com
96812498Sgiacomo.travaglini@arm.com    return NoFault;
96912498Sgiacomo.travaglini@arm.com}
97012498Sgiacomo.travaglini@arm.com
97113759Sgiacomo.gabrielli@arm.comFault
97213759Sgiacomo.gabrielli@arm.comArmStaticInst::sveAccessTrap(ExceptionLevel el) const
97313759Sgiacomo.gabrielli@arm.com{
97413759Sgiacomo.gabrielli@arm.com    switch (el) {
97513759Sgiacomo.gabrielli@arm.com      case EL1:
97613759Sgiacomo.gabrielli@arm.com        return std::make_shared<SupervisorTrap>(machInst, 0, EC_TRAPPED_SVE);
97713759Sgiacomo.gabrielli@arm.com      case EL2:
97813759Sgiacomo.gabrielli@arm.com        return std::make_shared<HypervisorTrap>(machInst, 0, EC_TRAPPED_SVE);
97913759Sgiacomo.gabrielli@arm.com      case EL3:
98013759Sgiacomo.gabrielli@arm.com        return std::make_shared<SecureMonitorTrap>(machInst, 0,
98113759Sgiacomo.gabrielli@arm.com                                                   EC_TRAPPED_SVE);
98213759Sgiacomo.gabrielli@arm.com
98313759Sgiacomo.gabrielli@arm.com      default:
98413759Sgiacomo.gabrielli@arm.com        panic("Illegal EL in sveAccessTrap\n");
98513759Sgiacomo.gabrielli@arm.com    }
98613759Sgiacomo.gabrielli@arm.com}
98713759Sgiacomo.gabrielli@arm.com
98813759Sgiacomo.gabrielli@arm.comFault
98913759Sgiacomo.gabrielli@arm.comArmStaticInst::checkSveTrap(ThreadContext *tc, CPSR cpsr) const
99013759Sgiacomo.gabrielli@arm.com{
99113759Sgiacomo.gabrielli@arm.com    const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
99213759Sgiacomo.gabrielli@arm.com
99313759Sgiacomo.gabrielli@arm.com    if (ArmSystem::haveVirtualization(tc) && el <= EL2) {
99413759Sgiacomo.gabrielli@arm.com        CPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL2);
99513759Sgiacomo.gabrielli@arm.com        if (cptrEnCheck.tz)
99613759Sgiacomo.gabrielli@arm.com            return sveAccessTrap(EL2);
99713759Sgiacomo.gabrielli@arm.com    }
99813759Sgiacomo.gabrielli@arm.com
99913759Sgiacomo.gabrielli@arm.com    if (ArmSystem::haveSecurity(tc)) {
100013759Sgiacomo.gabrielli@arm.com        CPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3);
100113759Sgiacomo.gabrielli@arm.com        if (!cptrEnCheck.ez)
100213759Sgiacomo.gabrielli@arm.com            return sveAccessTrap(EL3);
100313759Sgiacomo.gabrielli@arm.com    }
100413759Sgiacomo.gabrielli@arm.com
100513759Sgiacomo.gabrielli@arm.com    return NoFault;
100613759Sgiacomo.gabrielli@arm.com}
100713759Sgiacomo.gabrielli@arm.com
100813759Sgiacomo.gabrielli@arm.comFault
100913759Sgiacomo.gabrielli@arm.comArmStaticInst::checkSveEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
101013759Sgiacomo.gabrielli@arm.com{
101113759Sgiacomo.gabrielli@arm.com    const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
101213759Sgiacomo.gabrielli@arm.com    if ((el == EL0 && cpacr.zen != 0x3) ||
101313759Sgiacomo.gabrielli@arm.com        (el == EL1 && !(cpacr.zen & 0x1)))
101413759Sgiacomo.gabrielli@arm.com        return sveAccessTrap(EL1);
101513759Sgiacomo.gabrielli@arm.com
101613759Sgiacomo.gabrielli@arm.com    return checkSveTrap(tc, cpsr);
101713759Sgiacomo.gabrielli@arm.com}
101813759Sgiacomo.gabrielli@arm.com
101913759Sgiacomo.gabrielli@arm.com
102011514Sandreas.sandberg@arm.comstatic uint8_t
102111514Sandreas.sandberg@arm.comgetRestoredITBits(ThreadContext *tc, CPSR spsr)
102211514Sandreas.sandberg@arm.com{
102311514Sandreas.sandberg@arm.com    // See: shared/functions/system/RestoredITBits in the ARM ARM
102411514Sandreas.sandberg@arm.com
102511514Sandreas.sandberg@arm.com    const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode);
102611514Sandreas.sandberg@arm.com    const uint8_t it = itState(spsr);
102711514Sandreas.sandberg@arm.com
102811514Sandreas.sandberg@arm.com    if (!spsr.t || spsr.il)
102911514Sandreas.sandberg@arm.com        return 0;
103011514Sandreas.sandberg@arm.com
103111514Sandreas.sandberg@arm.com    // The IT bits are forced to zero when they are set to a reserved
103211514Sandreas.sandberg@arm.com    // value.
103311514Sandreas.sandberg@arm.com    if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0)
103411514Sandreas.sandberg@arm.com        return 0;
103511514Sandreas.sandberg@arm.com
103611514Sandreas.sandberg@arm.com    const bool itd = el == EL2 ?
103711514Sandreas.sandberg@arm.com        ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd :
103811514Sandreas.sandberg@arm.com        ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd;
103911514Sandreas.sandberg@arm.com
104011514Sandreas.sandberg@arm.com    // The IT bits are forced to zero when returning to A32 state, or
104111514Sandreas.sandberg@arm.com    // when returning to an EL with the ITD bit set to 1, and the IT
104211514Sandreas.sandberg@arm.com    // bits are describing a multi-instruction block.
104311514Sandreas.sandberg@arm.com    if (itd && bits(it, 2, 0) != 0)
104411514Sandreas.sandberg@arm.com        return 0;
104511514Sandreas.sandberg@arm.com
104611514Sandreas.sandberg@arm.com    return it;
104711513Sandreas.sandberg@arm.com}
104811514Sandreas.sandberg@arm.com
104911514Sandreas.sandberg@arm.comstatic bool
105011514Sandreas.sandberg@arm.comillegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
105111514Sandreas.sandberg@arm.com{
105211514Sandreas.sandberg@arm.com    const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode;
105312788Sgiacomo.travaglini@arm.com    if (unknownMode(mode))
105411514Sandreas.sandberg@arm.com        return true;
105511514Sandreas.sandberg@arm.com
105611514Sandreas.sandberg@arm.com    const OperatingMode cur_mode = (OperatingMode) (uint8_t)cpsr.mode;
105711514Sandreas.sandberg@arm.com    const ExceptionLevel target_el = opModeToEL(mode);
105812497Sgiacomo.travaglini@arm.com
105912497Sgiacomo.travaglini@arm.com    HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
106012497Sgiacomo.travaglini@arm.com    SCR scr = ((SCR)tc->readMiscReg(MISCREG_SCR_EL3));
106112497Sgiacomo.travaglini@arm.com
106211514Sandreas.sandberg@arm.com    if (target_el > opModeToEL(cur_mode))
106311514Sandreas.sandberg@arm.com        return true;
106411514Sandreas.sandberg@arm.com
106512497Sgiacomo.travaglini@arm.com    if (!ArmSystem::haveEL(tc, target_el))
106611514Sandreas.sandberg@arm.com        return true;
106711514Sandreas.sandberg@arm.com
106812497Sgiacomo.travaglini@arm.com    if (target_el == EL1 && ArmSystem::haveEL(tc, EL2) && scr.ns && hcr.tge)
106912497Sgiacomo.travaglini@arm.com        return true;
107012497Sgiacomo.travaglini@arm.com
107112497Sgiacomo.travaglini@arm.com    if (target_el == EL2 && ArmSystem::haveEL(tc, EL3) && !scr.ns)
107212497Sgiacomo.travaglini@arm.com        return true;
107312497Sgiacomo.travaglini@arm.com
107412497Sgiacomo.travaglini@arm.com    bool spsr_mode_is_aarch32 = (spsr.width == 1);
107512497Sgiacomo.travaglini@arm.com    bool known, target_el_is_aarch32;
107612497Sgiacomo.travaglini@arm.com    std::tie(known, target_el_is_aarch32) = ELUsingAArch32K(tc, target_el);
107712497Sgiacomo.travaglini@arm.com    assert(known || (target_el == EL0 && ELIs64(tc, EL1)));
107812497Sgiacomo.travaglini@arm.com
107912497Sgiacomo.travaglini@arm.com    if (known && (spsr_mode_is_aarch32 != target_el_is_aarch32))
108011514Sandreas.sandberg@arm.com        return true;
108111514Sandreas.sandberg@arm.com
108211514Sandreas.sandberg@arm.com    if (!spsr.width) {
108311514Sandreas.sandberg@arm.com        // aarch64
108411514Sandreas.sandberg@arm.com        if (!ArmSystem::highestELIs64(tc))
108511514Sandreas.sandberg@arm.com            return true;
108611514Sandreas.sandberg@arm.com        if (spsr & 0x2)
108711514Sandreas.sandberg@arm.com            return true;
108811514Sandreas.sandberg@arm.com        if (target_el == EL0 && spsr.sp)
108911514Sandreas.sandberg@arm.com            return true;
109011514Sandreas.sandberg@arm.com    } else {
109112497Sgiacomo.travaglini@arm.com        // aarch32
109212788Sgiacomo.travaglini@arm.com        return unknownMode32(mode);
109311514Sandreas.sandberg@arm.com    }
109411514Sandreas.sandberg@arm.com
109511514Sandreas.sandberg@arm.com    return false;
109611514Sandreas.sandberg@arm.com}
109711514Sandreas.sandberg@arm.com
109811514Sandreas.sandberg@arm.comCPSR
109911514Sandreas.sandberg@arm.comArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
110011514Sandreas.sandberg@arm.com{
110111514Sandreas.sandberg@arm.com    CPSR new_cpsr = 0;
110211514Sandreas.sandberg@arm.com
110311514Sandreas.sandberg@arm.com    // gem5 doesn't implement single-stepping, so force the SS bit to
110411514Sandreas.sandberg@arm.com    // 0.
110511514Sandreas.sandberg@arm.com    new_cpsr.ss = 0;
110611514Sandreas.sandberg@arm.com
110711514Sandreas.sandberg@arm.com    if (illegalExceptionReturn(tc, cpsr, spsr)) {
110812510Sgiacomo.travaglini@arm.com        // If the SPSR specifies an illegal exception return,
110912510Sgiacomo.travaglini@arm.com        // then PSTATE.{M, nRW, EL, SP} are unchanged and PSTATE.IL
111012510Sgiacomo.travaglini@arm.com        // is set to 1.
111111514Sandreas.sandberg@arm.com        new_cpsr.il = 1;
111212510Sgiacomo.travaglini@arm.com        if (cpsr.width) {
111312510Sgiacomo.travaglini@arm.com            new_cpsr.mode = cpsr.mode;
111412510Sgiacomo.travaglini@arm.com        } else {
111512510Sgiacomo.travaglini@arm.com            new_cpsr.width = cpsr.width;
111612510Sgiacomo.travaglini@arm.com            new_cpsr.el = cpsr.el;
111712510Sgiacomo.travaglini@arm.com            new_cpsr.sp = cpsr.sp;
111812510Sgiacomo.travaglini@arm.com        }
111911514Sandreas.sandberg@arm.com    } else {
112011514Sandreas.sandberg@arm.com        new_cpsr.il = spsr.il;
112112788Sgiacomo.travaglini@arm.com        if (spsr.width && unknownMode32((OperatingMode)(uint8_t)spsr.mode)) {
112211514Sandreas.sandberg@arm.com            new_cpsr.il = 1;
112311514Sandreas.sandberg@arm.com        } else if (spsr.width) {
112411514Sandreas.sandberg@arm.com            new_cpsr.mode = spsr.mode;
112511514Sandreas.sandberg@arm.com        } else {
112611514Sandreas.sandberg@arm.com            new_cpsr.el = spsr.el;
112711514Sandreas.sandberg@arm.com            new_cpsr.sp = spsr.sp;
112811514Sandreas.sandberg@arm.com        }
112911514Sandreas.sandberg@arm.com    }
113011514Sandreas.sandberg@arm.com
113111514Sandreas.sandberg@arm.com    new_cpsr.nz = spsr.nz;
113211514Sandreas.sandberg@arm.com    new_cpsr.c = spsr.c;
113311514Sandreas.sandberg@arm.com    new_cpsr.v = spsr.v;
113414128Sgiacomo.travaglini@arm.com    new_cpsr.pan = spsr.pan;
113511514Sandreas.sandberg@arm.com    if (new_cpsr.width) {
113611514Sandreas.sandberg@arm.com        // aarch32
113711514Sandreas.sandberg@arm.com        const ITSTATE it = getRestoredITBits(tc, spsr);
113811514Sandreas.sandberg@arm.com        new_cpsr.q = spsr.q;
113911514Sandreas.sandberg@arm.com        new_cpsr.ge = spsr.ge;
114011514Sandreas.sandberg@arm.com        new_cpsr.e = spsr.e;
114111514Sandreas.sandberg@arm.com        new_cpsr.aif = spsr.aif;
114211514Sandreas.sandberg@arm.com        new_cpsr.t = spsr.t;
114311514Sandreas.sandberg@arm.com        new_cpsr.it2 = it.top6;
114411514Sandreas.sandberg@arm.com        new_cpsr.it1 = it.bottom2;
114511514Sandreas.sandberg@arm.com    } else {
114611514Sandreas.sandberg@arm.com        // aarch64
114711514Sandreas.sandberg@arm.com        new_cpsr.daif = spsr.daif;
114811514Sandreas.sandberg@arm.com    }
114911514Sandreas.sandberg@arm.com
115011514Sandreas.sandberg@arm.com    return new_cpsr;
115111514Sandreas.sandberg@arm.com}
115211514Sandreas.sandberg@arm.com
115312498Sgiacomo.travaglini@arm.combool
115412498Sgiacomo.travaglini@arm.comArmStaticInst::generalExceptionsToAArch64(ThreadContext *tc,
115512498Sgiacomo.travaglini@arm.com                                          ExceptionLevel pstateEL) const
115612498Sgiacomo.travaglini@arm.com{
115712498Sgiacomo.travaglini@arm.com    // Returns TRUE if exceptions normally routed to EL1 are being handled
115812498Sgiacomo.travaglini@arm.com    // at an Exception level using AArch64, because either EL1 is using
115912498Sgiacomo.travaglini@arm.com    // AArch64 or TGE is in force and EL2 is using AArch64.
116012498Sgiacomo.travaglini@arm.com    HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
116112498Sgiacomo.travaglini@arm.com    return (pstateEL == EL0 && !ELIs32(tc, EL1)) ||
116212498Sgiacomo.travaglini@arm.com           (ArmSystem::haveEL(tc, EL2) && !inSecureState(tc) &&
116312498Sgiacomo.travaglini@arm.com               !ELIs32(tc, EL2) && hcr.tge);
116412498Sgiacomo.travaglini@arm.com}
116511514Sandreas.sandberg@arm.com
116613759Sgiacomo.gabrielli@arm.comunsigned
116713759Sgiacomo.gabrielli@arm.comArmStaticInst::getCurSveVecLenInBits(ThreadContext *tc)
116813759Sgiacomo.gabrielli@arm.com{
116913759Sgiacomo.gabrielli@arm.com    return tc->getIsaPtr()->getCurSveVecLenInBits(tc);
117013759Sgiacomo.gabrielli@arm.com}
117111514Sandreas.sandberg@arm.com
117211514Sandreas.sandberg@arm.com}
1173