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