static_inst.cc revision 12109
17094Sgblack@eecs.umich.edu/*
211513Sandreas.sandberg@arm.com * Copyright (c) 2010-2014, 2016 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
73811513Sandreas.sandberg@arm.com
73911514Sandreas.sandberg@arm.comstatic uint8_t
74011514Sandreas.sandberg@arm.comgetRestoredITBits(ThreadContext *tc, CPSR spsr)
74111514Sandreas.sandberg@arm.com{
74211514Sandreas.sandberg@arm.com    // See: shared/functions/system/RestoredITBits in the ARM ARM
74311514Sandreas.sandberg@arm.com
74411514Sandreas.sandberg@arm.com    const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode);
74511514Sandreas.sandberg@arm.com    const uint8_t it = itState(spsr);
74611514Sandreas.sandberg@arm.com
74711514Sandreas.sandberg@arm.com    if (!spsr.t || spsr.il)
74811514Sandreas.sandberg@arm.com        return 0;
74911514Sandreas.sandberg@arm.com
75011514Sandreas.sandberg@arm.com    // The IT bits are forced to zero when they are set to a reserved
75111514Sandreas.sandberg@arm.com    // value.
75211514Sandreas.sandberg@arm.com    if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0)
75311514Sandreas.sandberg@arm.com        return 0;
75411514Sandreas.sandberg@arm.com
75511514Sandreas.sandberg@arm.com    const bool itd = el == EL2 ?
75611514Sandreas.sandberg@arm.com        ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd :
75711514Sandreas.sandberg@arm.com        ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd;
75811514Sandreas.sandberg@arm.com
75911514Sandreas.sandberg@arm.com    // The IT bits are forced to zero when returning to A32 state, or
76011514Sandreas.sandberg@arm.com    // when returning to an EL with the ITD bit set to 1, and the IT
76111514Sandreas.sandberg@arm.com    // bits are describing a multi-instruction block.
76211514Sandreas.sandberg@arm.com    if (itd && bits(it, 2, 0) != 0)
76311514Sandreas.sandberg@arm.com        return 0;
76411514Sandreas.sandberg@arm.com
76511514Sandreas.sandberg@arm.com    return it;
76611513Sandreas.sandberg@arm.com}
76711514Sandreas.sandberg@arm.com
76811514Sandreas.sandberg@arm.comstatic bool
76911514Sandreas.sandberg@arm.comillegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
77011514Sandreas.sandberg@arm.com{
77111514Sandreas.sandberg@arm.com    const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode;
77211514Sandreas.sandberg@arm.com    if (badMode(mode))
77311514Sandreas.sandberg@arm.com        return true;
77411514Sandreas.sandberg@arm.com
77511514Sandreas.sandberg@arm.com    const OperatingMode cur_mode = (OperatingMode) (uint8_t)cpsr.mode;
77611514Sandreas.sandberg@arm.com    const ExceptionLevel target_el = opModeToEL(mode);
77711514Sandreas.sandberg@arm.com    if (target_el > opModeToEL(cur_mode))
77811514Sandreas.sandberg@arm.com        return true;
77911514Sandreas.sandberg@arm.com
78011514Sandreas.sandberg@arm.com    if (target_el == EL3 && !ArmSystem::haveSecurity(tc))
78111514Sandreas.sandberg@arm.com        return true;
78211514Sandreas.sandberg@arm.com
78311514Sandreas.sandberg@arm.com    if (target_el == EL2 && !ArmSystem::haveVirtualization(tc))
78411514Sandreas.sandberg@arm.com        return true;
78511514Sandreas.sandberg@arm.com
78611514Sandreas.sandberg@arm.com    if (!spsr.width) {
78711514Sandreas.sandberg@arm.com        // aarch64
78811514Sandreas.sandberg@arm.com        if (!ArmSystem::highestELIs64(tc))
78911514Sandreas.sandberg@arm.com            return true;
79011514Sandreas.sandberg@arm.com
79111514Sandreas.sandberg@arm.com        if (spsr & 0x2)
79211514Sandreas.sandberg@arm.com            return true;
79311514Sandreas.sandberg@arm.com        if (target_el == EL0 && spsr.sp)
79411514Sandreas.sandberg@arm.com            return true;
79511514Sandreas.sandberg@arm.com        if (target_el == EL2 && !((SCR)tc->readMiscReg(MISCREG_SCR_EL3)).ns)
79611514Sandreas.sandberg@arm.com            return false;
79711514Sandreas.sandberg@arm.com    } else {
79811514Sandreas.sandberg@arm.com        return badMode32(mode);
79911514Sandreas.sandberg@arm.com    }
80011514Sandreas.sandberg@arm.com
80111514Sandreas.sandberg@arm.com    return false;
80211514Sandreas.sandberg@arm.com}
80311514Sandreas.sandberg@arm.com
80411514Sandreas.sandberg@arm.comCPSR
80511514Sandreas.sandberg@arm.comArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
80611514Sandreas.sandberg@arm.com{
80711514Sandreas.sandberg@arm.com    CPSR new_cpsr = 0;
80811514Sandreas.sandberg@arm.com
80911514Sandreas.sandberg@arm.com    // gem5 doesn't implement single-stepping, so force the SS bit to
81011514Sandreas.sandberg@arm.com    // 0.
81111514Sandreas.sandberg@arm.com    new_cpsr.ss = 0;
81211514Sandreas.sandberg@arm.com
81311514Sandreas.sandberg@arm.com    if (illegalExceptionReturn(tc, cpsr, spsr)) {
81411514Sandreas.sandberg@arm.com        new_cpsr.il = 1;
81511514Sandreas.sandberg@arm.com    } else {
81611514Sandreas.sandberg@arm.com        new_cpsr.il = spsr.il;
81711514Sandreas.sandberg@arm.com        if (spsr.width && badMode32((OperatingMode)(uint8_t)spsr.mode)) {
81811514Sandreas.sandberg@arm.com            new_cpsr.il = 1;
81911514Sandreas.sandberg@arm.com        } else if (spsr.width) {
82011514Sandreas.sandberg@arm.com            new_cpsr.mode = spsr.mode;
82111514Sandreas.sandberg@arm.com        } else {
82211514Sandreas.sandberg@arm.com            new_cpsr.el = spsr.el;
82311514Sandreas.sandberg@arm.com            new_cpsr.sp = spsr.sp;
82411514Sandreas.sandberg@arm.com        }
82511514Sandreas.sandberg@arm.com    }
82611514Sandreas.sandberg@arm.com
82711514Sandreas.sandberg@arm.com    new_cpsr.nz = spsr.nz;
82811514Sandreas.sandberg@arm.com    new_cpsr.c = spsr.c;
82911514Sandreas.sandberg@arm.com    new_cpsr.v = spsr.v;
83011514Sandreas.sandberg@arm.com    if (new_cpsr.width) {
83111514Sandreas.sandberg@arm.com        // aarch32
83211514Sandreas.sandberg@arm.com        const ITSTATE it = getRestoredITBits(tc, spsr);
83311514Sandreas.sandberg@arm.com        new_cpsr.q = spsr.q;
83411514Sandreas.sandberg@arm.com        new_cpsr.ge = spsr.ge;
83511514Sandreas.sandberg@arm.com        new_cpsr.e = spsr.e;
83611514Sandreas.sandberg@arm.com        new_cpsr.aif = spsr.aif;
83711514Sandreas.sandberg@arm.com        new_cpsr.t = spsr.t;
83811514Sandreas.sandberg@arm.com        new_cpsr.it2 = it.top6;
83911514Sandreas.sandberg@arm.com        new_cpsr.it1 = it.bottom2;
84011514Sandreas.sandberg@arm.com    } else {
84111514Sandreas.sandberg@arm.com        // aarch64
84211514Sandreas.sandberg@arm.com        new_cpsr.daif = spsr.daif;
84311514Sandreas.sandberg@arm.com    }
84411514Sandreas.sandberg@arm.com
84511514Sandreas.sandberg@arm.com    return new_cpsr;
84611514Sandreas.sandberg@arm.com}
84711514Sandreas.sandberg@arm.com
84811514Sandreas.sandberg@arm.com
84911514Sandreas.sandberg@arm.com
85011514Sandreas.sandberg@arm.com}
851