static_inst.cc revision 12104
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
33412104Snathanael.premillieu@arm.comArmStaticInst::printCCReg(std::ostream &os, RegIndex reg_idx) const
33512104Snathanael.premillieu@arm.com{
33612104Snathanael.premillieu@arm.com    ccprintf(os, "cc_%s", ArmISA::ccRegName[reg_idx]);
33712104Snathanael.premillieu@arm.com}
33812104Snathanael.premillieu@arm.com
33912104Snathanael.premillieu@arm.comvoid
34012104Snathanael.premillieu@arm.comArmStaticInst::printMiscReg(std::ostream &os, RegIndex reg_idx) const
34112104Snathanael.premillieu@arm.com{
34212104Snathanael.premillieu@arm.com    assert(reg_idx < NUM_MISCREGS);
34312104Snathanael.premillieu@arm.com    ccprintf(os, "%s", ArmISA::miscRegName[reg_idx]);
3446253Sgblack@eecs.umich.edu}
3456253Sgblack@eecs.umich.edu
3466262Sgblack@eecs.umich.eduvoid
3477148Sgblack@eecs.umich.eduArmStaticInst::printMnemonic(std::ostream &os,
3486262Sgblack@eecs.umich.edu                             const std::string &suffix,
34910037SARM gem5 Developers                             bool withPred,
35010037SARM gem5 Developers                             bool withCond64,
35110037SARM gem5 Developers                             ConditionCode cond64) const
3526262Sgblack@eecs.umich.edu{
3536262Sgblack@eecs.umich.edu    os << "  " << mnemonic;
35410037SARM gem5 Developers    if (withPred && !aarch64) {
35510037SARM gem5 Developers        printCondition(os, machInst.condCode);
3567122Sgblack@eecs.umich.edu        os << suffix;
35710037SARM gem5 Developers    } else if (withCond64) {
35810037SARM gem5 Developers        os << ".";
35910037SARM gem5 Developers        printCondition(os, cond64);
36010037SARM gem5 Developers        os << suffix;
36110037SARM gem5 Developers    }
36210037SARM gem5 Developers    if (machInst.bigThumb)
36310037SARM gem5 Developers        os << ".w";
36410037SARM gem5 Developers    os << "   ";
36510037SARM gem5 Developers}
36610037SARM gem5 Developers
36710037SARM gem5 Developersvoid
36810037SARM gem5 DevelopersArmStaticInst::printTarget(std::ostream &os, Addr target,
36910037SARM gem5 Developers                           const SymbolTable *symtab) const
37010037SARM gem5 Developers{
37110037SARM gem5 Developers    Addr symbolAddr;
37210037SARM gem5 Developers    std::string symbol;
37310037SARM gem5 Developers
37410037SARM gem5 Developers    if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) {
37510037SARM gem5 Developers        ccprintf(os, "<%s", symbol);
37610037SARM gem5 Developers        if (symbolAddr != target)
37710037SARM gem5 Developers            ccprintf(os, "+%d>", target - symbolAddr);
37810037SARM gem5 Developers        else
37910037SARM gem5 Developers            ccprintf(os, ">");
38010037SARM gem5 Developers    } else {
38110037SARM gem5 Developers        ccprintf(os, "%#x", target);
38210037SARM gem5 Developers    }
38310037SARM gem5 Developers}
38410037SARM gem5 Developers
38510037SARM gem5 Developersvoid
38610037SARM gem5 DevelopersArmStaticInst::printCondition(std::ostream &os,
38710037SARM gem5 Developers                              unsigned code,
38810037SARM gem5 Developers                              bool noImplicit) const
38910037SARM gem5 Developers{
39010037SARM gem5 Developers    switch (code) {
39110037SARM gem5 Developers      case COND_EQ:
39210037SARM gem5 Developers        os << "eq";
39310037SARM gem5 Developers        break;
39410037SARM gem5 Developers      case COND_NE:
39510037SARM gem5 Developers        os << "ne";
39610037SARM gem5 Developers        break;
39710037SARM gem5 Developers      case COND_CS:
39810037SARM gem5 Developers        os << "cs";
39910037SARM gem5 Developers        break;
40010037SARM gem5 Developers      case COND_CC:
40110037SARM gem5 Developers        os << "cc";
40210037SARM gem5 Developers        break;
40310037SARM gem5 Developers      case COND_MI:
40410037SARM gem5 Developers        os << "mi";
40510037SARM gem5 Developers        break;
40610037SARM gem5 Developers      case COND_PL:
40710037SARM gem5 Developers        os << "pl";
40810037SARM gem5 Developers        break;
40910037SARM gem5 Developers      case COND_VS:
41010037SARM gem5 Developers        os << "vs";
41110037SARM gem5 Developers        break;
41210037SARM gem5 Developers      case COND_VC:
41310037SARM gem5 Developers        os << "vc";
41410037SARM gem5 Developers        break;
41510037SARM gem5 Developers      case COND_HI:
41610037SARM gem5 Developers        os << "hi";
41710037SARM gem5 Developers        break;
41810037SARM gem5 Developers      case COND_LS:
41910037SARM gem5 Developers        os << "ls";
42010037SARM gem5 Developers        break;
42110037SARM gem5 Developers      case COND_GE:
42210037SARM gem5 Developers        os << "ge";
42310037SARM gem5 Developers        break;
42410037SARM gem5 Developers      case COND_LT:
42510037SARM gem5 Developers        os << "lt";
42610037SARM gem5 Developers        break;
42710037SARM gem5 Developers      case COND_GT:
42810037SARM gem5 Developers        os << "gt";
42910037SARM gem5 Developers        break;
43010037SARM gem5 Developers      case COND_LE:
43110037SARM gem5 Developers        os << "le";
43210037SARM gem5 Developers        break;
43310037SARM gem5 Developers      case COND_AL:
43410037SARM gem5 Developers        // This one is implicit.
43510037SARM gem5 Developers        if (noImplicit)
43610037SARM gem5 Developers            os << "al";
43710037SARM gem5 Developers        break;
43810037SARM gem5 Developers      case COND_UC:
43910037SARM gem5 Developers        // Unconditional.
44010037SARM gem5 Developers        if (noImplicit)
44110037SARM gem5 Developers            os << "uc";
44210037SARM gem5 Developers        break;
44310037SARM gem5 Developers      default:
44410037SARM gem5 Developers        panic("Unrecognized condition code %d.\n", code);
4456262Sgblack@eecs.umich.edu    }
4466262Sgblack@eecs.umich.edu}
4476262Sgblack@eecs.umich.edu
4486263Sgblack@eecs.umich.eduvoid
4497148Sgblack@eecs.umich.eduArmStaticInst::printMemSymbol(std::ostream &os,
4506263Sgblack@eecs.umich.edu                              const SymbolTable *symtab,
4516263Sgblack@eecs.umich.edu                              const std::string &prefix,
4526263Sgblack@eecs.umich.edu                              const Addr addr,
4536263Sgblack@eecs.umich.edu                              const std::string &suffix) const
4546263Sgblack@eecs.umich.edu{
4556263Sgblack@eecs.umich.edu    Addr symbolAddr;
4566263Sgblack@eecs.umich.edu    std::string symbol;
4576263Sgblack@eecs.umich.edu    if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
4586263Sgblack@eecs.umich.edu        ccprintf(os, "%s%s", prefix, symbol);
4596263Sgblack@eecs.umich.edu        if (symbolAddr != addr)
4606263Sgblack@eecs.umich.edu            ccprintf(os, "+%d", addr - symbolAddr);
4616263Sgblack@eecs.umich.edu        ccprintf(os, suffix);
4626263Sgblack@eecs.umich.edu    }
4636263Sgblack@eecs.umich.edu}
4646263Sgblack@eecs.umich.edu
4656264Sgblack@eecs.umich.eduvoid
4667148Sgblack@eecs.umich.eduArmStaticInst::printShiftOperand(std::ostream &os,
4677142Sgblack@eecs.umich.edu                                     IntRegIndex rm,
4687142Sgblack@eecs.umich.edu                                     bool immShift,
4697142Sgblack@eecs.umich.edu                                     uint32_t shiftAmt,
4707142Sgblack@eecs.umich.edu                                     IntRegIndex rs,
4717142Sgblack@eecs.umich.edu                                     ArmShiftType type) const
4726264Sgblack@eecs.umich.edu{
4737142Sgblack@eecs.umich.edu    bool firstOp = false;
4746264Sgblack@eecs.umich.edu
4757142Sgblack@eecs.umich.edu    if (rm != INTREG_ZERO) {
47612104Snathanael.premillieu@arm.com        printIntReg(os, rm);
4777142Sgblack@eecs.umich.edu    }
4787142Sgblack@eecs.umich.edu
4796306Sgblack@eecs.umich.edu    bool done = false;
4806264Sgblack@eecs.umich.edu
4816306Sgblack@eecs.umich.edu    if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
4826306Sgblack@eecs.umich.edu        shiftAmt = 32;
4836264Sgblack@eecs.umich.edu
4846306Sgblack@eecs.umich.edu    switch (type) {
4856306Sgblack@eecs.umich.edu      case LSL:
4866306Sgblack@eecs.umich.edu        if (immShift && shiftAmt == 0) {
4876306Sgblack@eecs.umich.edu            done = true;
4886264Sgblack@eecs.umich.edu            break;
4896306Sgblack@eecs.umich.edu        }
4907142Sgblack@eecs.umich.edu        if (!firstOp)
4917142Sgblack@eecs.umich.edu            os << ", ";
4927142Sgblack@eecs.umich.edu        os << "LSL";
4936306Sgblack@eecs.umich.edu        break;
4946306Sgblack@eecs.umich.edu      case LSR:
4957142Sgblack@eecs.umich.edu        if (!firstOp)
4967142Sgblack@eecs.umich.edu            os << ", ";
4977142Sgblack@eecs.umich.edu        os << "LSR";
4986306Sgblack@eecs.umich.edu        break;
4996306Sgblack@eecs.umich.edu      case ASR:
5007142Sgblack@eecs.umich.edu        if (!firstOp)
5017142Sgblack@eecs.umich.edu            os << ", ";
5027142Sgblack@eecs.umich.edu        os << "ASR";
5036306Sgblack@eecs.umich.edu        break;
5046306Sgblack@eecs.umich.edu      case ROR:
5056306Sgblack@eecs.umich.edu        if (immShift && shiftAmt == 0) {
5067142Sgblack@eecs.umich.edu            if (!firstOp)
5077142Sgblack@eecs.umich.edu                os << ", ";
5087142Sgblack@eecs.umich.edu            os << "RRX";
5096306Sgblack@eecs.umich.edu            done = true;
5106264Sgblack@eecs.umich.edu            break;
5116264Sgblack@eecs.umich.edu        }
5127142Sgblack@eecs.umich.edu        if (!firstOp)
5137142Sgblack@eecs.umich.edu            os << ", ";
5147142Sgblack@eecs.umich.edu        os << "ROR";
5156306Sgblack@eecs.umich.edu        break;
5166306Sgblack@eecs.umich.edu      default:
5176306Sgblack@eecs.umich.edu        panic("Tried to disassemble unrecognized shift type.\n");
5186306Sgblack@eecs.umich.edu    }
5196306Sgblack@eecs.umich.edu    if (!done) {
5207142Sgblack@eecs.umich.edu        if (!firstOp)
5217142Sgblack@eecs.umich.edu            os << " ";
5226306Sgblack@eecs.umich.edu        if (immShift)
5236306Sgblack@eecs.umich.edu            os << "#" << shiftAmt;
5246306Sgblack@eecs.umich.edu        else
52512104Snathanael.premillieu@arm.com            printIntReg(os, rs);
5266264Sgblack@eecs.umich.edu    }
5276264Sgblack@eecs.umich.edu}
5286264Sgblack@eecs.umich.edu
5296264Sgblack@eecs.umich.eduvoid
53010037SARM gem5 DevelopersArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os,
53110037SARM gem5 Developers                                  IntRegIndex rm, ArmExtendType type,
53210037SARM gem5 Developers                                  int64_t shiftAmt) const
53310037SARM gem5 Developers{
53410037SARM gem5 Developers    if (!firstOperand)
53510037SARM gem5 Developers        ccprintf(os, ", ");
53612104Snathanael.premillieu@arm.com    printIntReg(os, rm);
53710037SARM gem5 Developers    if (type == UXTX && shiftAmt == 0)
53810037SARM gem5 Developers        return;
53910037SARM gem5 Developers    switch (type) {
54010037SARM gem5 Developers      case UXTB: ccprintf(os, ", UXTB");
54110037SARM gem5 Developers        break;
54210037SARM gem5 Developers      case UXTH: ccprintf(os, ", UXTH");
54310037SARM gem5 Developers        break;
54410037SARM gem5 Developers      case UXTW: ccprintf(os, ", UXTW");
54510037SARM gem5 Developers        break;
54610037SARM gem5 Developers      case UXTX: ccprintf(os, ", LSL");
54710037SARM gem5 Developers        break;
54810037SARM gem5 Developers      case SXTB: ccprintf(os, ", SXTB");
54910037SARM gem5 Developers        break;
55010037SARM gem5 Developers      case SXTH: ccprintf(os, ", SXTH");
55110037SARM gem5 Developers        break;
55210037SARM gem5 Developers      case SXTW: ccprintf(os, ", SXTW");
55310037SARM gem5 Developers        break;
55410037SARM gem5 Developers      case SXTX: ccprintf(os, ", SXTW");
55510037SARM gem5 Developers        break;
55610037SARM gem5 Developers    }
55710037SARM gem5 Developers    if (type == UXTX || shiftAmt)
55810037SARM gem5 Developers        ccprintf(os, " #%d", shiftAmt);
55910037SARM gem5 Developers}
56010037SARM gem5 Developers
56110037SARM gem5 Developersvoid
5627148Sgblack@eecs.umich.eduArmStaticInst::printDataInst(std::ostream &os, bool withImm,
5637142Sgblack@eecs.umich.edu        bool immShift, bool s, IntRegIndex rd, IntRegIndex rn,
5647142Sgblack@eecs.umich.edu        IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt,
56511371Snathanael.premillieu@arm.com        ArmShiftType type, uint64_t imm) const
5666264Sgblack@eecs.umich.edu{
5677142Sgblack@eecs.umich.edu    printMnemonic(os, s ? "s" : "");
5686264Sgblack@eecs.umich.edu    bool firstOp = true;
5696264Sgblack@eecs.umich.edu
5706264Sgblack@eecs.umich.edu    // Destination
5717142Sgblack@eecs.umich.edu    if (rd != INTREG_ZERO) {
5726264Sgblack@eecs.umich.edu        firstOp = false;
57312104Snathanael.premillieu@arm.com        printIntReg(os, rd);
5746264Sgblack@eecs.umich.edu    }
5756264Sgblack@eecs.umich.edu
5766264Sgblack@eecs.umich.edu    // Source 1.
5777142Sgblack@eecs.umich.edu    if (rn != INTREG_ZERO) {
5786264Sgblack@eecs.umich.edu        if (!firstOp)
5796264Sgblack@eecs.umich.edu            os << ", ";
5806264Sgblack@eecs.umich.edu        firstOp = false;
58112104Snathanael.premillieu@arm.com        printIntReg(os, rn);
5826264Sgblack@eecs.umich.edu    }
5836264Sgblack@eecs.umich.edu
5846264Sgblack@eecs.umich.edu    if (!firstOp)
5856264Sgblack@eecs.umich.edu        os << ", ";
5866306Sgblack@eecs.umich.edu    if (withImm) {
58711371Snathanael.premillieu@arm.com        ccprintf(os, "#%ld", imm);
5886306Sgblack@eecs.umich.edu    } else {
5897142Sgblack@eecs.umich.edu        printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
5906306Sgblack@eecs.umich.edu    }
5916264Sgblack@eecs.umich.edu}
5926264Sgblack@eecs.umich.edu
5936254Sgblack@eecs.umich.edustd::string
5947148Sgblack@eecs.umich.eduArmStaticInst::generateDisassembly(Addr pc,
5956254Sgblack@eecs.umich.edu                                   const SymbolTable *symtab) const
5966253Sgblack@eecs.umich.edu{
5976253Sgblack@eecs.umich.edu    std::stringstream ss;
5986262Sgblack@eecs.umich.edu    printMnemonic(ss);
5996253Sgblack@eecs.umich.edu    return ss.str();
6006253Sgblack@eecs.umich.edu}
60111513Sandreas.sandberg@arm.com
60211513Sandreas.sandberg@arm.com
60311513Sandreas.sandberg@arm.comFault
60411513Sandreas.sandberg@arm.comArmStaticInst::advSIMDFPAccessTrap64(ExceptionLevel el) const
60511513Sandreas.sandberg@arm.com{
60611513Sandreas.sandberg@arm.com    switch (el) {
60711513Sandreas.sandberg@arm.com      case EL1:
60811513Sandreas.sandberg@arm.com        return std::make_shared<SupervisorTrap>(machInst, 0x1E00000,
60911513Sandreas.sandberg@arm.com                                                EC_TRAPPED_SIMD_FP);
61011513Sandreas.sandberg@arm.com      case EL2:
61111513Sandreas.sandberg@arm.com        return std::make_shared<HypervisorTrap>(machInst, 0x1E00000,
61211513Sandreas.sandberg@arm.com                                                EC_TRAPPED_SIMD_FP);
61311513Sandreas.sandberg@arm.com      case EL3:
61411513Sandreas.sandberg@arm.com        return std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000,
61511513Sandreas.sandberg@arm.com                                                   EC_TRAPPED_SIMD_FP);
61611513Sandreas.sandberg@arm.com
61711513Sandreas.sandberg@arm.com      default:
61811513Sandreas.sandberg@arm.com        panic("Illegal EL in advSIMDFPAccessTrap64\n");
61911513Sandreas.sandberg@arm.com    }
6206253Sgblack@eecs.umich.edu}
62111513Sandreas.sandberg@arm.com
62211513Sandreas.sandberg@arm.com
62311513Sandreas.sandberg@arm.comFault
62411513Sandreas.sandberg@arm.comArmStaticInst::checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const
62511513Sandreas.sandberg@arm.com{
62611513Sandreas.sandberg@arm.com    const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el;
62711513Sandreas.sandberg@arm.com
62811513Sandreas.sandberg@arm.com    if (ArmSystem::haveVirtualization(tc) && el <= EL2) {
62911513Sandreas.sandberg@arm.com        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL2);
63011513Sandreas.sandberg@arm.com        if (cptrEnCheck.tfp)
63111513Sandreas.sandberg@arm.com            return advSIMDFPAccessTrap64(EL2);
63211513Sandreas.sandberg@arm.com    }
63311513Sandreas.sandberg@arm.com
63411513Sandreas.sandberg@arm.com    if (ArmSystem::haveSecurity(tc)) {
63511513Sandreas.sandberg@arm.com        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3);
63611513Sandreas.sandberg@arm.com        if (cptrEnCheck.tfp)
63711513Sandreas.sandberg@arm.com            return advSIMDFPAccessTrap64(EL3);
63811513Sandreas.sandberg@arm.com    }
63911513Sandreas.sandberg@arm.com
64011513Sandreas.sandberg@arm.com    return NoFault;
64111513Sandreas.sandberg@arm.com}
64211513Sandreas.sandberg@arm.com
64311513Sandreas.sandberg@arm.comFault
64411513Sandreas.sandberg@arm.comArmStaticInst::checkFPAdvSIMDEnabled64(ThreadContext *tc,
64511513Sandreas.sandberg@arm.com                                       CPSR cpsr, CPACR cpacr) const
64611513Sandreas.sandberg@arm.com{
64711513Sandreas.sandberg@arm.com    const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el;
64811513Sandreas.sandberg@arm.com    if ((el == EL0 && cpacr.fpen != 0x3) ||
64911513Sandreas.sandberg@arm.com        (el == EL1 && !(cpacr.fpen & 0x1)))
65011513Sandreas.sandberg@arm.com        return advSIMDFPAccessTrap64(EL1);
65111513Sandreas.sandberg@arm.com
65211513Sandreas.sandberg@arm.com    return checkFPAdvSIMDTrap64(tc, cpsr);
65311513Sandreas.sandberg@arm.com}
65411513Sandreas.sandberg@arm.com
65511513Sandreas.sandberg@arm.comFault
65611513Sandreas.sandberg@arm.comArmStaticInst::checkAdvSIMDOrFPEnabled32(ThreadContext *tc,
65711513Sandreas.sandberg@arm.com                                         CPSR cpsr, CPACR cpacr,
65811513Sandreas.sandberg@arm.com                                         NSACR nsacr, FPEXC fpexc,
65911513Sandreas.sandberg@arm.com                                         bool fpexc_check, bool advsimd) const
66011513Sandreas.sandberg@arm.com{
66111513Sandreas.sandberg@arm.com    const bool have_virtualization = ArmSystem::haveVirtualization(tc);
66211513Sandreas.sandberg@arm.com    const bool have_security = ArmSystem::haveSecurity(tc);
66311513Sandreas.sandberg@arm.com    const bool is_secure = inSecureState(tc);
66411513Sandreas.sandberg@arm.com    const ExceptionLevel cur_el = opModeToEL(currOpMode(tc));
66511513Sandreas.sandberg@arm.com
66611513Sandreas.sandberg@arm.com    if (cur_el == EL0 && ELIs64(tc, EL1))
66711513Sandreas.sandberg@arm.com        return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr);
66811513Sandreas.sandberg@arm.com
66911513Sandreas.sandberg@arm.com    uint8_t cpacr_cp10 = cpacr.cp10;
67011513Sandreas.sandberg@arm.com    bool cpacr_asedis = cpacr.asedis;
67111513Sandreas.sandberg@arm.com
67211513Sandreas.sandberg@arm.com    if (have_security && !ELIs64(tc, EL3) && !is_secure) {
67311513Sandreas.sandberg@arm.com        if (nsacr.nsasedis)
67411513Sandreas.sandberg@arm.com            cpacr_asedis = true;
67511513Sandreas.sandberg@arm.com        if (nsacr.cp10 == 0)
67611513Sandreas.sandberg@arm.com            cpacr_cp10 = 0;
67711513Sandreas.sandberg@arm.com    }
67811513Sandreas.sandberg@arm.com
67911513Sandreas.sandberg@arm.com    if (cur_el != EL2) {
68011513Sandreas.sandberg@arm.com        if (advsimd && cpacr_asedis)
68111513Sandreas.sandberg@arm.com            return disabledFault();
68211513Sandreas.sandberg@arm.com
68311513Sandreas.sandberg@arm.com        if ((cur_el == EL0 && cpacr_cp10 != 0x3) ||
68411513Sandreas.sandberg@arm.com            (cur_el != EL0 && !(cpacr_cp10 & 0x1)))
68511513Sandreas.sandberg@arm.com            return disabledFault();
68611513Sandreas.sandberg@arm.com    }
68711513Sandreas.sandberg@arm.com
68811513Sandreas.sandberg@arm.com    if (fpexc_check && !fpexc.en)
68911513Sandreas.sandberg@arm.com        return disabledFault();
69011513Sandreas.sandberg@arm.com
69111513Sandreas.sandberg@arm.com    // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap --
69211513Sandreas.sandberg@arm.com
69311513Sandreas.sandberg@arm.com    if (have_virtualization && !is_secure && ELIs64(tc, EL2))
69411513Sandreas.sandberg@arm.com        return checkFPAdvSIMDTrap64(tc, cpsr);
69511513Sandreas.sandberg@arm.com
69611513Sandreas.sandberg@arm.com    if (have_virtualization && !is_secure) {
69711513Sandreas.sandberg@arm.com        HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR);
69811513Sandreas.sandberg@arm.com        bool hcptr_cp10 = hcptr.tcp10;
69911513Sandreas.sandberg@arm.com        bool hcptr_tase = hcptr.tase;
70011513Sandreas.sandberg@arm.com
70111513Sandreas.sandberg@arm.com        if (have_security && !ELIs64(tc, EL3) && !is_secure) {
70211513Sandreas.sandberg@arm.com            if (nsacr.nsasedis)
70311513Sandreas.sandberg@arm.com                hcptr_tase = true;
70411513Sandreas.sandberg@arm.com            if (nsacr.cp10)
70511513Sandreas.sandberg@arm.com                hcptr_cp10 = true;
70611513Sandreas.sandberg@arm.com        }
70711513Sandreas.sandberg@arm.com
70811513Sandreas.sandberg@arm.com        if ((advsimd && hcptr_tase) || hcptr_cp10) {
70911513Sandreas.sandberg@arm.com            const uint32_t iss = advsimd ? (1 << 5) : 0xA;
71011513Sandreas.sandberg@arm.com            if (cur_el == EL2) {
71111513Sandreas.sandberg@arm.com                return std::make_shared<UndefinedInstruction>(
71211513Sandreas.sandberg@arm.com                    machInst, iss,
71311513Sandreas.sandberg@arm.com                    EC_TRAPPED_HCPTR, mnemonic);
71411513Sandreas.sandberg@arm.com            } else {
71511513Sandreas.sandberg@arm.com                return std::make_shared<HypervisorTrap>(
71611513Sandreas.sandberg@arm.com                    machInst, iss,
71711513Sandreas.sandberg@arm.com                    EC_TRAPPED_HCPTR);
71811513Sandreas.sandberg@arm.com            }
71911513Sandreas.sandberg@arm.com
72011513Sandreas.sandberg@arm.com        }
72111513Sandreas.sandberg@arm.com    }
72211513Sandreas.sandberg@arm.com
72311513Sandreas.sandberg@arm.com    if (have_security && ELIs64(tc, EL3)) {
72411513Sandreas.sandberg@arm.com        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3);
72511513Sandreas.sandberg@arm.com        if (cptrEnCheck.tfp)
72611513Sandreas.sandberg@arm.com            return advSIMDFPAccessTrap64(EL3);
72711513Sandreas.sandberg@arm.com    }
72811513Sandreas.sandberg@arm.com
72911513Sandreas.sandberg@arm.com    return NoFault;
73011513Sandreas.sandberg@arm.com}
73111513Sandreas.sandberg@arm.com
73211513Sandreas.sandberg@arm.com
73311514Sandreas.sandberg@arm.comstatic uint8_t
73411514Sandreas.sandberg@arm.comgetRestoredITBits(ThreadContext *tc, CPSR spsr)
73511514Sandreas.sandberg@arm.com{
73611514Sandreas.sandberg@arm.com    // See: shared/functions/system/RestoredITBits in the ARM ARM
73711514Sandreas.sandberg@arm.com
73811514Sandreas.sandberg@arm.com    const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode);
73911514Sandreas.sandberg@arm.com    const uint8_t it = itState(spsr);
74011514Sandreas.sandberg@arm.com
74111514Sandreas.sandberg@arm.com    if (!spsr.t || spsr.il)
74211514Sandreas.sandberg@arm.com        return 0;
74311514Sandreas.sandberg@arm.com
74411514Sandreas.sandberg@arm.com    // The IT bits are forced to zero when they are set to a reserved
74511514Sandreas.sandberg@arm.com    // value.
74611514Sandreas.sandberg@arm.com    if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0)
74711514Sandreas.sandberg@arm.com        return 0;
74811514Sandreas.sandberg@arm.com
74911514Sandreas.sandberg@arm.com    const bool itd = el == EL2 ?
75011514Sandreas.sandberg@arm.com        ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd :
75111514Sandreas.sandberg@arm.com        ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd;
75211514Sandreas.sandberg@arm.com
75311514Sandreas.sandberg@arm.com    // The IT bits are forced to zero when returning to A32 state, or
75411514Sandreas.sandberg@arm.com    // when returning to an EL with the ITD bit set to 1, and the IT
75511514Sandreas.sandberg@arm.com    // bits are describing a multi-instruction block.
75611514Sandreas.sandberg@arm.com    if (itd && bits(it, 2, 0) != 0)
75711514Sandreas.sandberg@arm.com        return 0;
75811514Sandreas.sandberg@arm.com
75911514Sandreas.sandberg@arm.com    return it;
76011513Sandreas.sandberg@arm.com}
76111514Sandreas.sandberg@arm.com
76211514Sandreas.sandberg@arm.comstatic bool
76311514Sandreas.sandberg@arm.comillegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
76411514Sandreas.sandberg@arm.com{
76511514Sandreas.sandberg@arm.com    const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode;
76611514Sandreas.sandberg@arm.com    if (badMode(mode))
76711514Sandreas.sandberg@arm.com        return true;
76811514Sandreas.sandberg@arm.com
76911514Sandreas.sandberg@arm.com    const OperatingMode cur_mode = (OperatingMode) (uint8_t)cpsr.mode;
77011514Sandreas.sandberg@arm.com    const ExceptionLevel target_el = opModeToEL(mode);
77111514Sandreas.sandberg@arm.com    if (target_el > opModeToEL(cur_mode))
77211514Sandreas.sandberg@arm.com        return true;
77311514Sandreas.sandberg@arm.com
77411514Sandreas.sandberg@arm.com    if (target_el == EL3 && !ArmSystem::haveSecurity(tc))
77511514Sandreas.sandberg@arm.com        return true;
77611514Sandreas.sandberg@arm.com
77711514Sandreas.sandberg@arm.com    if (target_el == EL2 && !ArmSystem::haveVirtualization(tc))
77811514Sandreas.sandberg@arm.com        return true;
77911514Sandreas.sandberg@arm.com
78011514Sandreas.sandberg@arm.com    if (!spsr.width) {
78111514Sandreas.sandberg@arm.com        // aarch64
78211514Sandreas.sandberg@arm.com        if (!ArmSystem::highestELIs64(tc))
78311514Sandreas.sandberg@arm.com            return true;
78411514Sandreas.sandberg@arm.com
78511514Sandreas.sandberg@arm.com        if (spsr & 0x2)
78611514Sandreas.sandberg@arm.com            return true;
78711514Sandreas.sandberg@arm.com        if (target_el == EL0 && spsr.sp)
78811514Sandreas.sandberg@arm.com            return true;
78911514Sandreas.sandberg@arm.com        if (target_el == EL2 && !((SCR)tc->readMiscReg(MISCREG_SCR_EL3)).ns)
79011514Sandreas.sandberg@arm.com            return false;
79111514Sandreas.sandberg@arm.com    } else {
79211514Sandreas.sandberg@arm.com        return badMode32(mode);
79311514Sandreas.sandberg@arm.com    }
79411514Sandreas.sandberg@arm.com
79511514Sandreas.sandberg@arm.com    return false;
79611514Sandreas.sandberg@arm.com}
79711514Sandreas.sandberg@arm.com
79811514Sandreas.sandberg@arm.comCPSR
79911514Sandreas.sandberg@arm.comArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
80011514Sandreas.sandberg@arm.com{
80111514Sandreas.sandberg@arm.com    CPSR new_cpsr = 0;
80211514Sandreas.sandberg@arm.com
80311514Sandreas.sandberg@arm.com    // gem5 doesn't implement single-stepping, so force the SS bit to
80411514Sandreas.sandberg@arm.com    // 0.
80511514Sandreas.sandberg@arm.com    new_cpsr.ss = 0;
80611514Sandreas.sandberg@arm.com
80711514Sandreas.sandberg@arm.com    if (illegalExceptionReturn(tc, cpsr, spsr)) {
80811514Sandreas.sandberg@arm.com        new_cpsr.il = 1;
80911514Sandreas.sandberg@arm.com    } else {
81011514Sandreas.sandberg@arm.com        new_cpsr.il = spsr.il;
81111514Sandreas.sandberg@arm.com        if (spsr.width && badMode32((OperatingMode)(uint8_t)spsr.mode)) {
81211514Sandreas.sandberg@arm.com            new_cpsr.il = 1;
81311514Sandreas.sandberg@arm.com        } else if (spsr.width) {
81411514Sandreas.sandberg@arm.com            new_cpsr.mode = spsr.mode;
81511514Sandreas.sandberg@arm.com        } else {
81611514Sandreas.sandberg@arm.com            new_cpsr.el = spsr.el;
81711514Sandreas.sandberg@arm.com            new_cpsr.sp = spsr.sp;
81811514Sandreas.sandberg@arm.com        }
81911514Sandreas.sandberg@arm.com    }
82011514Sandreas.sandberg@arm.com
82111514Sandreas.sandberg@arm.com    new_cpsr.nz = spsr.nz;
82211514Sandreas.sandberg@arm.com    new_cpsr.c = spsr.c;
82311514Sandreas.sandberg@arm.com    new_cpsr.v = spsr.v;
82411514Sandreas.sandberg@arm.com    if (new_cpsr.width) {
82511514Sandreas.sandberg@arm.com        // aarch32
82611514Sandreas.sandberg@arm.com        const ITSTATE it = getRestoredITBits(tc, spsr);
82711514Sandreas.sandberg@arm.com        new_cpsr.q = spsr.q;
82811514Sandreas.sandberg@arm.com        new_cpsr.ge = spsr.ge;
82911514Sandreas.sandberg@arm.com        new_cpsr.e = spsr.e;
83011514Sandreas.sandberg@arm.com        new_cpsr.aif = spsr.aif;
83111514Sandreas.sandberg@arm.com        new_cpsr.t = spsr.t;
83211514Sandreas.sandberg@arm.com        new_cpsr.it2 = it.top6;
83311514Sandreas.sandberg@arm.com        new_cpsr.it1 = it.bottom2;
83411514Sandreas.sandberg@arm.com    } else {
83511514Sandreas.sandberg@arm.com        // aarch64
83611514Sandreas.sandberg@arm.com        new_cpsr.daif = spsr.daif;
83711514Sandreas.sandberg@arm.com    }
83811514Sandreas.sandberg@arm.com
83911514Sandreas.sandberg@arm.com    return new_cpsr;
84011514Sandreas.sandberg@arm.com}
84111514Sandreas.sandberg@arm.com
84211514Sandreas.sandberg@arm.com
84311514Sandreas.sandberg@arm.com
84411514Sandreas.sandberg@arm.com}
845