17093Sgblack@eecs.umich.edu/* 212498Sgiacomo.travaglini@arm.com * Copyright (c) 2010-2013,2016-2018 ARM Limited 37093Sgblack@eecs.umich.edu * All rights reserved 47093Sgblack@eecs.umich.edu * 57093Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67093Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77093Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87093Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97093Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107093Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117093Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127093Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137093Sgblack@eecs.umich.edu * 147093Sgblack@eecs.umich.edu * Copyright (c) 2007-2008 The Florida State University 156253Sgblack@eecs.umich.edu * All rights reserved. 166253Sgblack@eecs.umich.edu * 176253Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 186253Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 196253Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 206253Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 216253Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 226253Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 236253Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 246253Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 256253Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 266253Sgblack@eecs.umich.edu * this software without specific prior written permission. 276253Sgblack@eecs.umich.edu * 286253Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 296253Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 306253Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 316253Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 326253Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 336253Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 346253Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 356253Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 366253Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 376253Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 386253Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 396253Sgblack@eecs.umich.edu * 406253Sgblack@eecs.umich.edu * Authors: Stephen Hines 416253Sgblack@eecs.umich.edu */ 426253Sgblack@eecs.umich.edu#ifndef __ARCH_ARM_INSTS_STATICINST_HH__ 436253Sgblack@eecs.umich.edu#define __ARCH_ARM_INSTS_STATICINST_HH__ 446253Sgblack@eecs.umich.edu 4510474Sandreas.hansson@arm.com#include <memory> 4610474Sandreas.hansson@arm.com 477640Sgblack@eecs.umich.edu#include "arch/arm/faults.hh" 487692SAli.Saidi@ARM.com#include "arch/arm/utility.hh" 4910037SARM gem5 Developers#include "arch/arm/system.hh" 506253Sgblack@eecs.umich.edu#include "base/trace.hh" 5112234Sgabeblack@google.com#include "cpu/exec_context.hh" 526253Sgblack@eecs.umich.edu#include "cpu/static_inst.hh" 538737Skoansin.tan@gmail.com#include "sim/byteswap.hh" 548782Sgblack@eecs.umich.edu#include "sim/full_system.hh" 556253Sgblack@eecs.umich.edu 566253Sgblack@eecs.umich.edunamespace ArmISA 576253Sgblack@eecs.umich.edu{ 587424Sgblack@eecs.umich.edu 597148Sgblack@eecs.umich.educlass ArmStaticInst : public StaticInst 606254Sgblack@eecs.umich.edu{ 616254Sgblack@eecs.umich.edu protected: 6210037SARM gem5 Developers bool aarch64; 6310037SARM gem5 Developers uint8_t intWidth; 6410037SARM gem5 Developers 656255Sgblack@eecs.umich.edu int32_t shift_rm_imm(uint32_t base, uint32_t shamt, 666255Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const; 676255Sgblack@eecs.umich.edu int32_t shift_rm_rs(uint32_t base, uint32_t shamt, 686255Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const; 696254Sgblack@eecs.umich.edu 706255Sgblack@eecs.umich.edu bool shift_carry_imm(uint32_t base, uint32_t shamt, 716255Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const; 726255Sgblack@eecs.umich.edu bool shift_carry_rs(uint32_t base, uint32_t shamt, 736255Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const; 746254Sgblack@eecs.umich.edu 7510037SARM gem5 Developers int64_t shiftReg64(uint64_t base, uint64_t shiftAmt, 7610037SARM gem5 Developers ArmShiftType type, uint8_t width) const; 7710037SARM gem5 Developers int64_t extendReg64(uint64_t base, ArmExtendType type, 7810037SARM gem5 Developers uint64_t shiftAmt, uint8_t width) const; 7910037SARM gem5 Developers 807193Sgblack@eecs.umich.edu template<int width> 817424Sgblack@eecs.umich.edu static inline bool 827193Sgblack@eecs.umich.edu saturateOp(int32_t &res, int64_t op1, int64_t op2, bool sub=false) 837193Sgblack@eecs.umich.edu { 847193Sgblack@eecs.umich.edu int64_t midRes = sub ? (op1 - op2) : (op1 + op2); 857193Sgblack@eecs.umich.edu if (bits(midRes, width) != bits(midRes, width - 1)) { 867193Sgblack@eecs.umich.edu if (midRes > 0) 877226Sgblack@eecs.umich.edu res = (LL(1) << (width - 1)) - 1; 887193Sgblack@eecs.umich.edu else 897226Sgblack@eecs.umich.edu res = -(LL(1) << (width - 1)); 907193Sgblack@eecs.umich.edu return true; 917193Sgblack@eecs.umich.edu } else { 927193Sgblack@eecs.umich.edu res = midRes; 937193Sgblack@eecs.umich.edu return false; 947193Sgblack@eecs.umich.edu } 957193Sgblack@eecs.umich.edu } 967193Sgblack@eecs.umich.edu 977424Sgblack@eecs.umich.edu static inline bool 987226Sgblack@eecs.umich.edu satInt(int32_t &res, int64_t op, int width) 997226Sgblack@eecs.umich.edu { 1007226Sgblack@eecs.umich.edu width--; 1017226Sgblack@eecs.umich.edu if (op >= (LL(1) << width)) { 1027226Sgblack@eecs.umich.edu res = (LL(1) << width) - 1; 1037226Sgblack@eecs.umich.edu return true; 1047226Sgblack@eecs.umich.edu } else if (op < -(LL(1) << width)) { 1057226Sgblack@eecs.umich.edu res = -(LL(1) << width); 1067226Sgblack@eecs.umich.edu return true; 1077226Sgblack@eecs.umich.edu } else { 1087226Sgblack@eecs.umich.edu res = op; 1097226Sgblack@eecs.umich.edu return false; 1107226Sgblack@eecs.umich.edu } 1117226Sgblack@eecs.umich.edu } 1127226Sgblack@eecs.umich.edu 1137219Sgblack@eecs.umich.edu template<int width> 1147424Sgblack@eecs.umich.edu static inline bool 1157219Sgblack@eecs.umich.edu uSaturateOp(uint32_t &res, int64_t op1, int64_t op2, bool sub=false) 1167219Sgblack@eecs.umich.edu { 1177219Sgblack@eecs.umich.edu int64_t midRes = sub ? (op1 - op2) : (op1 + op2); 1187226Sgblack@eecs.umich.edu if (midRes >= (LL(1) << width)) { 1197226Sgblack@eecs.umich.edu res = (LL(1) << width) - 1; 1207219Sgblack@eecs.umich.edu return true; 1217219Sgblack@eecs.umich.edu } else if (midRes < 0) { 1227219Sgblack@eecs.umich.edu res = 0; 1237219Sgblack@eecs.umich.edu return true; 1247219Sgblack@eecs.umich.edu } else { 1257219Sgblack@eecs.umich.edu res = midRes; 1267219Sgblack@eecs.umich.edu return false; 1277219Sgblack@eecs.umich.edu } 1287219Sgblack@eecs.umich.edu } 1297219Sgblack@eecs.umich.edu 1307424Sgblack@eecs.umich.edu static inline bool 1317226Sgblack@eecs.umich.edu uSatInt(int32_t &res, int64_t op, int width) 1327226Sgblack@eecs.umich.edu { 1337226Sgblack@eecs.umich.edu if (op >= (LL(1) << width)) { 1347226Sgblack@eecs.umich.edu res = (LL(1) << width) - 1; 1357226Sgblack@eecs.umich.edu return true; 1367226Sgblack@eecs.umich.edu } else if (op < 0) { 1377226Sgblack@eecs.umich.edu res = 0; 1387226Sgblack@eecs.umich.edu return true; 1397226Sgblack@eecs.umich.edu } else { 1407226Sgblack@eecs.umich.edu res = op; 1417226Sgblack@eecs.umich.edu return false; 1427226Sgblack@eecs.umich.edu } 1437226Sgblack@eecs.umich.edu } 1447226Sgblack@eecs.umich.edu 1456254Sgblack@eecs.umich.edu // Constructor 1467148Sgblack@eecs.umich.edu ArmStaticInst(const char *mnem, ExtMachInst _machInst, 1477148Sgblack@eecs.umich.edu OpClass __opClass) 1486254Sgblack@eecs.umich.edu : StaticInst(mnem, _machInst, __opClass) 1496253Sgblack@eecs.umich.edu { 15010037SARM gem5 Developers aarch64 = machInst.aarch64; 15110037SARM gem5 Developers if (bits(machInst, 28, 24) == 0x10) 15210037SARM gem5 Developers intWidth = 64; // Force 64-bit width for ADR/ADRP 15310037SARM gem5 Developers else 15410037SARM gem5 Developers intWidth = (aarch64 && bits(machInst, 31)) ? 64 : 32; 1556254Sgblack@eecs.umich.edu } 1566253Sgblack@eecs.umich.edu 1576254Sgblack@eecs.umich.edu /// Print a register name for disassembly given the unique 1586254Sgblack@eecs.umich.edu /// dependence tag number (FP or int). 15913759Sgiacomo.gabrielli@arm.com void printIntReg(std::ostream &os, RegIndex reg_idx, 16013759Sgiacomo.gabrielli@arm.com uint8_t opWidth = 0) const; 16112104Snathanael.premillieu@arm.com void printFloatReg(std::ostream &os, RegIndex reg_idx) const; 16213759Sgiacomo.gabrielli@arm.com void printVecReg(std::ostream &os, RegIndex reg_idx, 16313759Sgiacomo.gabrielli@arm.com bool isSveVecReg = false) const; 16413759Sgiacomo.gabrielli@arm.com void printVecPredReg(std::ostream &os, RegIndex reg_idx) const; 16512104Snathanael.premillieu@arm.com void printCCReg(std::ostream &os, RegIndex reg_idx) const; 16612104Snathanael.premillieu@arm.com void printMiscReg(std::ostream &os, RegIndex reg_idx) const; 1676262Sgblack@eecs.umich.edu void printMnemonic(std::ostream &os, 1686262Sgblack@eecs.umich.edu const std::string &suffix = "", 16910037SARM gem5 Developers bool withPred = true, 17010037SARM gem5 Developers bool withCond64 = false, 17110037SARM gem5 Developers ConditionCode cond64 = COND_UC) const; 17210037SARM gem5 Developers void printTarget(std::ostream &os, Addr target, 17310037SARM gem5 Developers const SymbolTable *symtab) const; 17410037SARM gem5 Developers void printCondition(std::ostream &os, unsigned code, 17510037SARM gem5 Developers bool noImplicit=false) const; 1766263Sgblack@eecs.umich.edu void printMemSymbol(std::ostream &os, const SymbolTable *symtab, 1776263Sgblack@eecs.umich.edu const std::string &prefix, const Addr addr, 1786263Sgblack@eecs.umich.edu const std::string &suffix) const; 1797142Sgblack@eecs.umich.edu void printShiftOperand(std::ostream &os, IntRegIndex rm, 1807142Sgblack@eecs.umich.edu bool immShift, uint32_t shiftAmt, 1817142Sgblack@eecs.umich.edu IntRegIndex rs, ArmShiftType type) const; 18210037SARM gem5 Developers void printExtendOperand(bool firstOperand, std::ostream &os, 18310037SARM gem5 Developers IntRegIndex rm, ArmExtendType type, 18410037SARM gem5 Developers int64_t shiftAmt) const; 18513369Syuetsu.kodama@riken.jp void printPFflags(std::ostream &os, int flag) const; 1866253Sgblack@eecs.umich.edu 1876306Sgblack@eecs.umich.edu void printDataInst(std::ostream &os, bool withImm) const; 1887142Sgblack@eecs.umich.edu void printDataInst(std::ostream &os, bool withImm, bool immShift, bool s, 1897142Sgblack@eecs.umich.edu IntRegIndex rd, IntRegIndex rn, IntRegIndex rm, 1907142Sgblack@eecs.umich.edu IntRegIndex rs, uint32_t shiftAmt, ArmShiftType type, 19111371Snathanael.premillieu@arm.com uint64_t imm) const; 1926264Sgblack@eecs.umich.edu 1937720Sgblack@eecs.umich.edu void 19412616Sgabeblack@google.com advancePC(PCState &pcState) const override 1957720Sgblack@eecs.umich.edu { 1967720Sgblack@eecs.umich.edu pcState.advance(); 1977720Sgblack@eecs.umich.edu } 1987720Sgblack@eecs.umich.edu 19912616Sgabeblack@google.com std::string generateDisassembly( 20012616Sgabeblack@google.com Addr pc, const SymbolTable *symtab) const override; 2016748Sgblack@eecs.umich.edu 2027424Sgblack@eecs.umich.edu static inline uint32_t 20310037SARM gem5 Developers cpsrWriteByInstr(CPSR cpsr, uint32_t val, SCR scr, NSACR nsacr, 20410037SARM gem5 Developers uint8_t byteMask, bool affectState, bool nmfi, ThreadContext *tc) 2056748Sgblack@eecs.umich.edu { 20610037SARM gem5 Developers bool privileged = (cpsr.mode != MODE_USER); 20710037SARM gem5 Developers bool haveVirt = ArmSystem::haveVirtualization(tc); 20810037SARM gem5 Developers bool haveSecurity = ArmSystem::haveSecurity(tc); 20910037SARM gem5 Developers bool isSecure = inSecureState(scr, cpsr) || !haveSecurity; 2106748Sgblack@eecs.umich.edu 2116748Sgblack@eecs.umich.edu uint32_t bitMask = 0; 2126748Sgblack@eecs.umich.edu 2136748Sgblack@eecs.umich.edu if (bits(byteMask, 3)) { 2146748Sgblack@eecs.umich.edu unsigned lowIdx = affectState ? 24 : 27; 2156748Sgblack@eecs.umich.edu bitMask = bitMask | mask(31, lowIdx); 2166748Sgblack@eecs.umich.edu } 2176748Sgblack@eecs.umich.edu if (bits(byteMask, 2)) { 2186748Sgblack@eecs.umich.edu bitMask = bitMask | mask(19, 16); 2196748Sgblack@eecs.umich.edu } 2206748Sgblack@eecs.umich.edu if (bits(byteMask, 1)) { 2216748Sgblack@eecs.umich.edu unsigned highIdx = affectState ? 15 : 9; 22210037SARM gem5 Developers unsigned lowIdx = (privileged && (isSecure || scr.aw || haveVirt)) 22310037SARM gem5 Developers ? 8 : 9; 2246748Sgblack@eecs.umich.edu bitMask = bitMask | mask(highIdx, lowIdx); 2256748Sgblack@eecs.umich.edu } 2266748Sgblack@eecs.umich.edu if (bits(byteMask, 0)) { 2276748Sgblack@eecs.umich.edu if (privileged) { 22810037SARM gem5 Developers bitMask |= 1 << 7; 22910037SARM gem5 Developers if ( (!nmfi || !((val >> 6) & 0x1)) && 23010037SARM gem5 Developers (isSecure || scr.fw || haveVirt) ) { 23110037SARM gem5 Developers bitMask |= 1 << 6; 23210037SARM gem5 Developers } 23310037SARM gem5 Developers // Now check the new mode is allowed 23410037SARM gem5 Developers OperatingMode newMode = (OperatingMode) (val & mask(5)); 23510037SARM gem5 Developers OperatingMode oldMode = (OperatingMode)(uint32_t)cpsr.mode; 23612788Sgiacomo.travaglini@arm.com if (!badMode(tc, newMode)) { 23710037SARM gem5 Developers bool validModeChange = true; 23810037SARM gem5 Developers // Check for attempts to enter modes only permitted in 23910037SARM gem5 Developers // Secure state from Non-secure state. These are Monitor 24010037SARM gem5 Developers // mode ('10110'), and FIQ mode ('10001') if the Security 24110037SARM gem5 Developers // Extensions have reserved it. 24210037SARM gem5 Developers if (!isSecure && newMode == MODE_MON) 24310037SARM gem5 Developers validModeChange = false; 24410037SARM gem5 Developers if (!isSecure && newMode == MODE_FIQ && nsacr.rfr == '1') 24510037SARM gem5 Developers validModeChange = false; 24610037SARM gem5 Developers // There is no Hyp mode ('11010') in Secure state, so that 24710037SARM gem5 Developers // is UNPREDICTABLE 24810037SARM gem5 Developers if (scr.ns == '0' && newMode == MODE_HYP) 24910037SARM gem5 Developers validModeChange = false; 25010037SARM gem5 Developers // Cannot move into Hyp mode directly from a Non-secure 25110037SARM gem5 Developers // PL1 mode 25210037SARM gem5 Developers if (!isSecure && oldMode != MODE_HYP && newMode == MODE_HYP) 25310037SARM gem5 Developers validModeChange = false; 25410037SARM gem5 Developers // Cannot move out of Hyp mode with this function except 25510037SARM gem5 Developers // on an exception return 25610037SARM gem5 Developers if (oldMode == MODE_HYP && newMode != MODE_HYP && !affectState) 25710037SARM gem5 Developers validModeChange = false; 25810037SARM gem5 Developers // Must not change to 64 bit when running in 32 bit mode 25910037SARM gem5 Developers if (!opModeIs64(oldMode) && opModeIs64(newMode)) 26010037SARM gem5 Developers validModeChange = false; 26110037SARM gem5 Developers 26210037SARM gem5 Developers // If we passed all of the above then set the bit mask to 26310037SARM gem5 Developers // copy the mode accross 26410037SARM gem5 Developers if (validModeChange) { 26510037SARM gem5 Developers bitMask = bitMask | mask(5); 26610037SARM gem5 Developers } else { 26710037SARM gem5 Developers warn_once("Illegal change to CPSR mode attempted\n"); 26810037SARM gem5 Developers } 2697317Sgblack@eecs.umich.edu } else { 2707317Sgblack@eecs.umich.edu warn_once("Ignoring write of bad mode to CPSR.\n"); 2717317Sgblack@eecs.umich.edu } 2726748Sgblack@eecs.umich.edu } 2736748Sgblack@eecs.umich.edu if (affectState) 2746748Sgblack@eecs.umich.edu bitMask = bitMask | (1 << 5); 2756748Sgblack@eecs.umich.edu } 2766748Sgblack@eecs.umich.edu 27710037SARM gem5 Developers return ((uint32_t)cpsr & ~bitMask) | (val & bitMask); 2786748Sgblack@eecs.umich.edu } 2796748Sgblack@eecs.umich.edu 2807424Sgblack@eecs.umich.edu static inline uint32_t 2816748Sgblack@eecs.umich.edu spsrWriteByInstr(uint32_t spsr, uint32_t val, 2826748Sgblack@eecs.umich.edu uint8_t byteMask, bool affectState) 2836748Sgblack@eecs.umich.edu { 2846748Sgblack@eecs.umich.edu uint32_t bitMask = 0; 2856748Sgblack@eecs.umich.edu 2866748Sgblack@eecs.umich.edu if (bits(byteMask, 3)) 2876748Sgblack@eecs.umich.edu bitMask = bitMask | mask(31, 24); 2886748Sgblack@eecs.umich.edu if (bits(byteMask, 2)) 2896748Sgblack@eecs.umich.edu bitMask = bitMask | mask(19, 16); 2906748Sgblack@eecs.umich.edu if (bits(byteMask, 1)) 2916748Sgblack@eecs.umich.edu bitMask = bitMask | mask(15, 8); 2926748Sgblack@eecs.umich.edu if (bits(byteMask, 0)) 2936748Sgblack@eecs.umich.edu bitMask = bitMask | mask(7, 0); 2946748Sgblack@eecs.umich.edu 2956748Sgblack@eecs.umich.edu return ((spsr & ~bitMask) | (val & bitMask)); 2966748Sgblack@eecs.umich.edu } 2977093Sgblack@eecs.umich.edu 2987424Sgblack@eecs.umich.edu static inline Addr 29912234Sgabeblack@google.com readPC(ExecContext *xc) 3007147Sgblack@eecs.umich.edu { 3017720Sgblack@eecs.umich.edu return xc->pcState().instPC(); 3027147Sgblack@eecs.umich.edu } 3037147Sgblack@eecs.umich.edu 3047424Sgblack@eecs.umich.edu static inline void 30512234Sgabeblack@google.com setNextPC(ExecContext *xc, Addr val) 3067093Sgblack@eecs.umich.edu { 3077720Sgblack@eecs.umich.edu PCState pc = xc->pcState(); 3087720Sgblack@eecs.umich.edu pc.instNPC(val); 3097720Sgblack@eecs.umich.edu xc->pcState(pc); 3107093Sgblack@eecs.umich.edu } 3117094Sgblack@eecs.umich.edu 3127296Sgblack@eecs.umich.edu template<class T> 3137424Sgblack@eecs.umich.edu static inline T 3147296Sgblack@eecs.umich.edu cSwap(T val, bool big) 3157296Sgblack@eecs.umich.edu { 3167296Sgblack@eecs.umich.edu if (big) { 3177296Sgblack@eecs.umich.edu return gtobe(val); 3187296Sgblack@eecs.umich.edu } else { 3197296Sgblack@eecs.umich.edu return gtole(val); 3207296Sgblack@eecs.umich.edu } 3217296Sgblack@eecs.umich.edu } 3227296Sgblack@eecs.umich.edu 3237639Sgblack@eecs.umich.edu template<class T, class E> 3247639Sgblack@eecs.umich.edu static inline T 3257639Sgblack@eecs.umich.edu cSwap(T val, bool big) 3267639Sgblack@eecs.umich.edu { 3277639Sgblack@eecs.umich.edu const unsigned count = sizeof(T) / sizeof(E); 3287639Sgblack@eecs.umich.edu union { 3297639Sgblack@eecs.umich.edu T tVal; 3307639Sgblack@eecs.umich.edu E eVals[count]; 3317639Sgblack@eecs.umich.edu } conv; 3327639Sgblack@eecs.umich.edu conv.tVal = htog(val); 3337639Sgblack@eecs.umich.edu if (big) { 3347639Sgblack@eecs.umich.edu for (unsigned i = 0; i < count; i++) { 3357639Sgblack@eecs.umich.edu conv.eVals[i] = gtobe(conv.eVals[i]); 3367639Sgblack@eecs.umich.edu } 3377639Sgblack@eecs.umich.edu } else { 3387639Sgblack@eecs.umich.edu for (unsigned i = 0; i < count; i++) { 3397639Sgblack@eecs.umich.edu conv.eVals[i] = gtole(conv.eVals[i]); 3407639Sgblack@eecs.umich.edu } 3417639Sgblack@eecs.umich.edu } 3427639Sgblack@eecs.umich.edu return gtoh(conv.tVal); 3437639Sgblack@eecs.umich.edu } 3447639Sgblack@eecs.umich.edu 3457148Sgblack@eecs.umich.edu // Perform an interworking branch. 3467424Sgblack@eecs.umich.edu static inline void 34712234Sgabeblack@google.com setIWNextPC(ExecContext *xc, Addr val) 3487094Sgblack@eecs.umich.edu { 3497720Sgblack@eecs.umich.edu PCState pc = xc->pcState(); 3507720Sgblack@eecs.umich.edu pc.instIWNPC(val); 3517720Sgblack@eecs.umich.edu xc->pcState(pc); 3527094Sgblack@eecs.umich.edu } 3537148Sgblack@eecs.umich.edu 3547148Sgblack@eecs.umich.edu // Perform an interworking branch in ARM mode, a regular branch 3557148Sgblack@eecs.umich.edu // otherwise. 3567424Sgblack@eecs.umich.edu static inline void 35712234Sgabeblack@google.com setAIWNextPC(ExecContext *xc, Addr val) 3587148Sgblack@eecs.umich.edu { 3597720Sgblack@eecs.umich.edu PCState pc = xc->pcState(); 3607720Sgblack@eecs.umich.edu pc.instAIWNPC(val); 3617720Sgblack@eecs.umich.edu xc->pcState(pc); 3627148Sgblack@eecs.umich.edu } 3637640Sgblack@eecs.umich.edu 3647640Sgblack@eecs.umich.edu inline Fault 3657640Sgblack@eecs.umich.edu disabledFault() const 3667640Sgblack@eecs.umich.edu { 36710474Sandreas.hansson@arm.com return std::make_shared<UndefinedInstruction>(machInst, false, 36810474Sandreas.hansson@arm.com mnemonic, true); 3697640Sgblack@eecs.umich.edu } 37010037SARM gem5 Developers 37112403Sgiacomo.travaglini@arm.com // Utility function used by checkForWFxTrap32 and checkForWFxTrap64 37212403Sgiacomo.travaglini@arm.com // Returns true if processor has to trap a WFI/WFE instruction. 37312403Sgiacomo.travaglini@arm.com bool isWFxTrapping(ThreadContext *tc, 37412403Sgiacomo.travaglini@arm.com ExceptionLevel targetEL, bool isWfe) const; 37512403Sgiacomo.travaglini@arm.com 37611513Sandreas.sandberg@arm.com /** 37712789Sgiacomo.travaglini@arm.com * Trigger a Software Breakpoint. 37812789Sgiacomo.travaglini@arm.com * 37912789Sgiacomo.travaglini@arm.com * See aarch32/exceptions/debug/AArch32.SoftwareBreakpoint in the 38012789Sgiacomo.travaglini@arm.com * ARM ARM psueodcode library. 38112789Sgiacomo.travaglini@arm.com */ 38212789Sgiacomo.travaglini@arm.com Fault softwareBreakpoint32(ExecContext *xc, uint16_t imm) const; 38312789Sgiacomo.travaglini@arm.com 38412789Sgiacomo.travaglini@arm.com /** 38511513Sandreas.sandberg@arm.com * Trap an access to Advanced SIMD or FP registers due to access 38611513Sandreas.sandberg@arm.com * control bits. 38711513Sandreas.sandberg@arm.com * 38811513Sandreas.sandberg@arm.com * See aarch64/exceptions/traps/AArch64.AdvSIMDFPAccessTrap in the 38911513Sandreas.sandberg@arm.com * ARM ARM psueodcode library. 39011513Sandreas.sandberg@arm.com * 39111513Sandreas.sandberg@arm.com * @param el Target EL for the trap 39211513Sandreas.sandberg@arm.com */ 39311513Sandreas.sandberg@arm.com Fault advSIMDFPAccessTrap64(ExceptionLevel el) const; 39411513Sandreas.sandberg@arm.com 39511513Sandreas.sandberg@arm.com 39611513Sandreas.sandberg@arm.com /** 39711513Sandreas.sandberg@arm.com * Check an Advaned SIMD access against CPTR_EL2 and CPTR_EL3. 39811513Sandreas.sandberg@arm.com * 39911513Sandreas.sandberg@arm.com * See aarch64/exceptions/traps/AArch64.CheckFPAdvSIMDTrap in the 40011513Sandreas.sandberg@arm.com * ARM ARM psueodcode library. 40111513Sandreas.sandberg@arm.com */ 40211513Sandreas.sandberg@arm.com Fault checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const; 40311513Sandreas.sandberg@arm.com 40411513Sandreas.sandberg@arm.com /** 40511513Sandreas.sandberg@arm.com * Check an Advaned SIMD access against CPACR_EL1, CPTR_EL2, and 40611513Sandreas.sandberg@arm.com * CPTR_EL3. 40711513Sandreas.sandberg@arm.com * 40811513Sandreas.sandberg@arm.com * See aarch64/exceptions/traps/AArch64.CheckFPAdvSIMDEnabled in the 40911513Sandreas.sandberg@arm.com * ARM ARM psueodcode library. 41011513Sandreas.sandberg@arm.com */ 41111513Sandreas.sandberg@arm.com Fault checkFPAdvSIMDEnabled64(ThreadContext *tc, 41211513Sandreas.sandberg@arm.com CPSR cpsr, CPACR cpacr) const; 41311513Sandreas.sandberg@arm.com 41411513Sandreas.sandberg@arm.com /** 41511513Sandreas.sandberg@arm.com * Check if a VFP/SIMD access from aarch32 should be allowed. 41611513Sandreas.sandberg@arm.com * 41711513Sandreas.sandberg@arm.com * See aarch32/exceptions/traps/AArch32.CheckAdvSIMDOrFPEnabled in the 41811513Sandreas.sandberg@arm.com * ARM ARM psueodcode library. 41911513Sandreas.sandberg@arm.com */ 42011513Sandreas.sandberg@arm.com Fault checkAdvSIMDOrFPEnabled32(ThreadContext *tc, 42111513Sandreas.sandberg@arm.com CPSR cpsr, CPACR cpacr, 42211513Sandreas.sandberg@arm.com NSACR nsacr, FPEXC fpexc, 42311513Sandreas.sandberg@arm.com bool fpexc_check, bool advsimd) const; 42411513Sandreas.sandberg@arm.com 42511514Sandreas.sandberg@arm.com /** 42612403Sgiacomo.travaglini@arm.com * Check if WFE/WFI instruction execution in aarch32 should be trapped. 42712403Sgiacomo.travaglini@arm.com * 42812403Sgiacomo.travaglini@arm.com * See aarch32/exceptions/traps/AArch32.checkForWFxTrap in the 42912403Sgiacomo.travaglini@arm.com * ARM ARM psueodcode library. 43012403Sgiacomo.travaglini@arm.com */ 43112403Sgiacomo.travaglini@arm.com Fault checkForWFxTrap32(ThreadContext *tc, 43212403Sgiacomo.travaglini@arm.com ExceptionLevel tgtEl, bool isWfe) const; 43312403Sgiacomo.travaglini@arm.com 43412403Sgiacomo.travaglini@arm.com /** 43512403Sgiacomo.travaglini@arm.com * Check if WFE/WFI instruction execution in aarch64 should be trapped. 43612403Sgiacomo.travaglini@arm.com * 43712403Sgiacomo.travaglini@arm.com * See aarch64/exceptions/traps/AArch64.checkForWFxTrap in the 43812403Sgiacomo.travaglini@arm.com * ARM ARM psueodcode library. 43912403Sgiacomo.travaglini@arm.com */ 44012403Sgiacomo.travaglini@arm.com Fault checkForWFxTrap64(ThreadContext *tc, 44112403Sgiacomo.travaglini@arm.com ExceptionLevel tgtEl, bool isWfe) const; 44212403Sgiacomo.travaglini@arm.com 44312403Sgiacomo.travaglini@arm.com /** 44412403Sgiacomo.travaglini@arm.com * WFE/WFI trapping helper function. 44512403Sgiacomo.travaglini@arm.com */ 44612403Sgiacomo.travaglini@arm.com Fault trapWFx(ThreadContext *tc, CPSR cpsr, SCR scr, bool isWfe) const; 44712403Sgiacomo.travaglini@arm.com 44812403Sgiacomo.travaglini@arm.com /** 44912498Sgiacomo.travaglini@arm.com * Check if SETEND instruction execution in aarch32 should be trapped. 45012498Sgiacomo.travaglini@arm.com * 45112498Sgiacomo.travaglini@arm.com * See aarch32/exceptions/traps/AArch32.CheckSETENDEnabled in the 45212498Sgiacomo.travaglini@arm.com * ARM ARM pseudocode library. 45312498Sgiacomo.travaglini@arm.com */ 45412498Sgiacomo.travaglini@arm.com Fault checkSETENDEnabled(ThreadContext *tc, CPSR cpsr) const; 45512498Sgiacomo.travaglini@arm.com 45612498Sgiacomo.travaglini@arm.com /** 45712498Sgiacomo.travaglini@arm.com * UNDEFINED behaviour in AArch32 45812498Sgiacomo.travaglini@arm.com * 45912498Sgiacomo.travaglini@arm.com * See aarch32/exceptions/traps/AArch32.UndefinedFault in the 46012498Sgiacomo.travaglini@arm.com * ARM ARM pseudocode library. 46112498Sgiacomo.travaglini@arm.com */ 46212498Sgiacomo.travaglini@arm.com Fault undefinedFault32(ThreadContext *tc, ExceptionLevel el) const; 46312498Sgiacomo.travaglini@arm.com 46412498Sgiacomo.travaglini@arm.com /** 46512498Sgiacomo.travaglini@arm.com * UNDEFINED behaviour in AArch64 46612498Sgiacomo.travaglini@arm.com * 46712498Sgiacomo.travaglini@arm.com * See aarch64/exceptions/traps/AArch64.UndefinedFault in the 46812498Sgiacomo.travaglini@arm.com * ARM ARM pseudocode library. 46912498Sgiacomo.travaglini@arm.com */ 47012498Sgiacomo.travaglini@arm.com Fault undefinedFault64(ThreadContext *tc, ExceptionLevel el) const; 47112498Sgiacomo.travaglini@arm.com 47212498Sgiacomo.travaglini@arm.com /** 47313759Sgiacomo.gabrielli@arm.com * Trap an access to SVE registers due to access control bits. 47413759Sgiacomo.gabrielli@arm.com * 47513759Sgiacomo.gabrielli@arm.com * @param el Target EL for the trap. 47613759Sgiacomo.gabrielli@arm.com */ 47713759Sgiacomo.gabrielli@arm.com Fault sveAccessTrap(ExceptionLevel el) const; 47813759Sgiacomo.gabrielli@arm.com 47913759Sgiacomo.gabrielli@arm.com /** 48013759Sgiacomo.gabrielli@arm.com * Check an SVE access against CPTR_EL2 and CPTR_EL3. 48113759Sgiacomo.gabrielli@arm.com */ 48213759Sgiacomo.gabrielli@arm.com Fault checkSveTrap(ThreadContext *tc, CPSR cpsr) const; 48313759Sgiacomo.gabrielli@arm.com 48413759Sgiacomo.gabrielli@arm.com /** 48513759Sgiacomo.gabrielli@arm.com * Check an SVE access against CPACR_EL1, CPTR_EL2, and CPTR_EL3. 48613759Sgiacomo.gabrielli@arm.com */ 48713759Sgiacomo.gabrielli@arm.com Fault checkSveEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const; 48813759Sgiacomo.gabrielli@arm.com 48913759Sgiacomo.gabrielli@arm.com /** 49011514Sandreas.sandberg@arm.com * Get the new PSTATE from a SPSR register in preparation for an 49111514Sandreas.sandberg@arm.com * exception return. 49211514Sandreas.sandberg@arm.com * 49311514Sandreas.sandberg@arm.com * See shared/functions/system/SetPSTATEFromPSR in the ARM ARM 49412498Sgiacomo.travaglini@arm.com * pseudocode library. 49511514Sandreas.sandberg@arm.com */ 49611514Sandreas.sandberg@arm.com CPSR getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const; 49711514Sandreas.sandberg@arm.com 49812498Sgiacomo.travaglini@arm.com /** 49912498Sgiacomo.travaglini@arm.com * Return true if exceptions normally routed to EL1 are being handled 50012498Sgiacomo.travaglini@arm.com * at an Exception level using AArch64, because either EL1 is using 50112498Sgiacomo.travaglini@arm.com * AArch64 or TGE is in force and EL2 is using AArch64. 50212498Sgiacomo.travaglini@arm.com * 50312498Sgiacomo.travaglini@arm.com * See aarch32/exceptions/exceptions/AArch32.GeneralExceptionsToAArch64 50412498Sgiacomo.travaglini@arm.com * in the ARM ARM pseudocode library. 50512498Sgiacomo.travaglini@arm.com */ 50612498Sgiacomo.travaglini@arm.com bool generalExceptionsToAArch64(ThreadContext *tc, 50712498Sgiacomo.travaglini@arm.com ExceptionLevel pstateEL) const; 50812498Sgiacomo.travaglini@arm.com 50910037SARM gem5 Developers public: 51010037SARM gem5 Developers virtual void 51110037SARM gem5 Developers annotateFault(ArmFault *fault) {} 51212249Sgiacomo.travaglini@arm.com 51312249Sgiacomo.travaglini@arm.com uint8_t 51412249Sgiacomo.travaglini@arm.com getIntWidth() const 51512249Sgiacomo.travaglini@arm.com { 51612249Sgiacomo.travaglini@arm.com return intWidth; 51712249Sgiacomo.travaglini@arm.com } 51812399Sgiacomo.travaglini@arm.com 51912399Sgiacomo.travaglini@arm.com /** Returns the byte size of current instruction */ 52012399Sgiacomo.travaglini@arm.com ssize_t 52112399Sgiacomo.travaglini@arm.com instSize() const 52212399Sgiacomo.travaglini@arm.com { 52312399Sgiacomo.travaglini@arm.com return (!machInst.thumb || machInst.bigThumb) ? 4 : 2; 52412399Sgiacomo.travaglini@arm.com } 52512399Sgiacomo.travaglini@arm.com 52612399Sgiacomo.travaglini@arm.com /** 52712399Sgiacomo.travaglini@arm.com * Returns the real encoding of the instruction: 52812399Sgiacomo.travaglini@arm.com * the machInst field is in fact always 64 bit wide and 52912399Sgiacomo.travaglini@arm.com * contains some instruction metadata, which means it differs 53012399Sgiacomo.travaglini@arm.com * from the real opcode. 53112399Sgiacomo.travaglini@arm.com */ 53212399Sgiacomo.travaglini@arm.com MachInst 53312399Sgiacomo.travaglini@arm.com encoding() const 53412399Sgiacomo.travaglini@arm.com { 53512401Sgiacomo.travaglini@arm.com return static_cast<MachInst>(machInst & (mask(instSize() * 8))); 53612399Sgiacomo.travaglini@arm.com } 53712614Sgabeblack@google.com 53812614Sgabeblack@google.com size_t 53912614Sgabeblack@google.com asBytes(void *buf, size_t max_size) override 54012614Sgabeblack@google.com { 54112614Sgabeblack@google.com return simpleAsBytes(buf, max_size, machInst); 54212614Sgabeblack@google.com } 54313759Sgiacomo.gabrielli@arm.com 54413759Sgiacomo.gabrielli@arm.com static unsigned getCurSveVecLenInBits(ThreadContext *tc); 54513759Sgiacomo.gabrielli@arm.com 54613759Sgiacomo.gabrielli@arm.com static unsigned 54713759Sgiacomo.gabrielli@arm.com getCurSveVecLenInQWords(ThreadContext *tc) 54813759Sgiacomo.gabrielli@arm.com { 54913759Sgiacomo.gabrielli@arm.com return getCurSveVecLenInBits(tc) >> 6; 55013759Sgiacomo.gabrielli@arm.com } 55113759Sgiacomo.gabrielli@arm.com 55213759Sgiacomo.gabrielli@arm.com template<typename T> 55313759Sgiacomo.gabrielli@arm.com static unsigned 55413759Sgiacomo.gabrielli@arm.com getCurSveVecLen(ThreadContext *tc) 55513759Sgiacomo.gabrielli@arm.com { 55613759Sgiacomo.gabrielli@arm.com return getCurSveVecLenInBits(tc) / (8 * sizeof(T)); 55713759Sgiacomo.gabrielli@arm.com } 5587094Sgblack@eecs.umich.edu}; 5596253Sgblack@eecs.umich.edu} 5606253Sgblack@eecs.umich.edu 5616253Sgblack@eecs.umich.edu#endif //__ARCH_ARM_INSTS_STATICINST_HH__ 562