static_inst.cc revision 11793
17094Sgblack@eecs.umich.edu/* 211513Sandreas.sandberg@arm.com * Copyright (c) 2010-2014, 2016 ARM Limited 39913Ssteve.reinhardt@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 47094Sgblack@eecs.umich.edu * All rights reserved 57094Sgblack@eecs.umich.edu * 67094Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 77094Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 87094Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 97094Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 107094Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 117094Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 127094Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 137094Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 147094Sgblack@eecs.umich.edu * 157094Sgblack@eecs.umich.edu * Copyright (c) 2007-2008 The Florida State University 166253Sgblack@eecs.umich.edu * All rights reserved. 176253Sgblack@eecs.umich.edu * 186253Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 196253Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 206253Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 216253Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 226253Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 236253Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 246253Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 256253Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 266253Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 276253Sgblack@eecs.umich.edu * this software without specific prior written permission. 286253Sgblack@eecs.umich.edu * 296253Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 306253Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316253Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 326253Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 336253Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 346253Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 356253Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 366253Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 376253Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 386253Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 396253Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 406253Sgblack@eecs.umich.edu * 416253Sgblack@eecs.umich.edu * Authors: Stephen Hines 426253Sgblack@eecs.umich.edu */ 436253Sgblack@eecs.umich.edu 448229Snate@binkert.org#include "arch/arm/insts/static_inst.hh" 4511793Sbrandon.potter@amd.com 466759SAli.Saidi@ARM.com#include "arch/arm/faults.hh" 476255Sgblack@eecs.umich.edu#include "base/condcodes.hh" 486712Snate@binkert.org#include "base/cprintf.hh" 4911793Sbrandon.potter@amd.com#include "base/loader/symtab.hh" 509913Ssteve.reinhardt@amd.com#include "cpu/reg_class.hh" 516253Sgblack@eecs.umich.edu 526253Sgblack@eecs.umich.edunamespace ArmISA 536253Sgblack@eecs.umich.edu{ 546254Sgblack@eecs.umich.edu// Shift Rm by an immediate value 556254Sgblack@eecs.umich.eduint32_t 567148Sgblack@eecs.umich.eduArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt, 577094Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const 586254Sgblack@eecs.umich.edu{ 596255Sgblack@eecs.umich.edu assert(shamt < 32); 606255Sgblack@eecs.umich.edu ArmShiftType shiftType; 616255Sgblack@eecs.umich.edu shiftType = (ArmShiftType)type; 626254Sgblack@eecs.umich.edu 636254Sgblack@eecs.umich.edu switch (shiftType) 646254Sgblack@eecs.umich.edu { 656255Sgblack@eecs.umich.edu case LSL: 666255Sgblack@eecs.umich.edu return base << shamt; 676255Sgblack@eecs.umich.edu case LSR: 686255Sgblack@eecs.umich.edu if (shamt == 0) 696255Sgblack@eecs.umich.edu return 0; 706255Sgblack@eecs.umich.edu else 716255Sgblack@eecs.umich.edu return base >> shamt; 726255Sgblack@eecs.umich.edu case ASR: 736255Sgblack@eecs.umich.edu if (shamt == 0) 747182Sgblack@eecs.umich.edu return (base >> 31) | -((base & (1 << 31)) >> 31); 756255Sgblack@eecs.umich.edu else 767182Sgblack@eecs.umich.edu return (base >> shamt) | -((base & (1 << 31)) >> shamt); 776255Sgblack@eecs.umich.edu case ROR: 786255Sgblack@eecs.umich.edu if (shamt == 0) 796255Sgblack@eecs.umich.edu return (cfval << 31) | (base >> 1); // RRX 806255Sgblack@eecs.umich.edu else 816255Sgblack@eecs.umich.edu return (base << (32 - shamt)) | (base >> shamt); 826255Sgblack@eecs.umich.edu default: 836712Snate@binkert.org ccprintf(std::cerr, "Unhandled shift type\n"); 846255Sgblack@eecs.umich.edu exit(1); 856255Sgblack@eecs.umich.edu break; 866254Sgblack@eecs.umich.edu } 876254Sgblack@eecs.umich.edu return 0; 886254Sgblack@eecs.umich.edu} 896254Sgblack@eecs.umich.edu 9010037SARM gem5 Developersint64_t 9110037SARM gem5 DevelopersArmStaticInst::shiftReg64(uint64_t base, uint64_t shiftAmt, 9210037SARM gem5 Developers ArmShiftType type, uint8_t width) const 9310037SARM gem5 Developers{ 9410037SARM gem5 Developers shiftAmt = shiftAmt % width; 9510037SARM gem5 Developers ArmShiftType shiftType; 9610037SARM gem5 Developers shiftType = (ArmShiftType)type; 9710037SARM gem5 Developers 9810037SARM gem5 Developers switch (shiftType) 9910037SARM gem5 Developers { 10010037SARM gem5 Developers case LSL: 10110037SARM gem5 Developers return base << shiftAmt; 10210037SARM gem5 Developers case LSR: 10310037SARM gem5 Developers if (shiftAmt == 0) 10410037SARM gem5 Developers return base; 10510037SARM gem5 Developers else 10610037SARM gem5 Developers return (base & mask(width)) >> shiftAmt; 10710037SARM gem5 Developers case ASR: 10810037SARM gem5 Developers if (shiftAmt == 0) { 10910037SARM gem5 Developers return base; 11010037SARM gem5 Developers } else { 11110037SARM gem5 Developers int sign_bit = bits(base, intWidth - 1); 11210037SARM gem5 Developers base >>= shiftAmt; 11310037SARM gem5 Developers base = sign_bit ? (base | ~mask(intWidth - shiftAmt)) : base; 11410037SARM gem5 Developers return base & mask(intWidth); 11510037SARM gem5 Developers } 11610037SARM gem5 Developers case ROR: 11710037SARM gem5 Developers if (shiftAmt == 0) 11810037SARM gem5 Developers return base; 11910037SARM gem5 Developers else 12010037SARM gem5 Developers return (base << (width - shiftAmt)) | (base >> shiftAmt); 12110037SARM gem5 Developers default: 12210037SARM gem5 Developers ccprintf(std::cerr, "Unhandled shift type\n"); 12310037SARM gem5 Developers exit(1); 12410037SARM gem5 Developers break; 12510037SARM gem5 Developers } 12610037SARM gem5 Developers return 0; 12710037SARM gem5 Developers} 12810037SARM gem5 Developers 12910037SARM gem5 Developersint64_t 13010037SARM gem5 DevelopersArmStaticInst::extendReg64(uint64_t base, ArmExtendType type, 13110037SARM gem5 Developers uint64_t shiftAmt, uint8_t width) const 13210037SARM gem5 Developers{ 13310037SARM gem5 Developers bool sign_extend = false; 13410037SARM gem5 Developers int len = 0; 13510037SARM gem5 Developers switch (type) { 13610037SARM gem5 Developers case UXTB: 13710037SARM gem5 Developers len = 8; 13810037SARM gem5 Developers break; 13910037SARM gem5 Developers case UXTH: 14010037SARM gem5 Developers len = 16; 14110037SARM gem5 Developers break; 14210037SARM gem5 Developers case UXTW: 14310037SARM gem5 Developers len = 32; 14410037SARM gem5 Developers break; 14510037SARM gem5 Developers case UXTX: 14610037SARM gem5 Developers len = 64; 14710037SARM gem5 Developers break; 14810037SARM gem5 Developers case SXTB: 14910037SARM gem5 Developers len = 8; 15010037SARM gem5 Developers sign_extend = true; 15110037SARM gem5 Developers break; 15210037SARM gem5 Developers case SXTH: 15310037SARM gem5 Developers len = 16; 15410037SARM gem5 Developers sign_extend = true; 15510037SARM gem5 Developers break; 15610037SARM gem5 Developers case SXTW: 15710037SARM gem5 Developers len = 32; 15810037SARM gem5 Developers sign_extend = true; 15910037SARM gem5 Developers break; 16010037SARM gem5 Developers case SXTX: 16110037SARM gem5 Developers len = 64; 16210037SARM gem5 Developers sign_extend = true; 16310037SARM gem5 Developers break; 16410037SARM gem5 Developers } 16510037SARM gem5 Developers len = len <= width - shiftAmt ? len : width - shiftAmt; 16610037SARM gem5 Developers uint64_t tmp = (uint64_t) bits(base, len - 1, 0) << shiftAmt; 16710037SARM gem5 Developers if (sign_extend) { 16810037SARM gem5 Developers int sign_bit = bits(tmp, len + shiftAmt - 1); 16910037SARM gem5 Developers tmp = sign_bit ? (tmp | ~mask(len + shiftAmt)) : tmp; 17010037SARM gem5 Developers } 17110037SARM gem5 Developers return tmp & mask(width); 17210037SARM gem5 Developers} 17310037SARM gem5 Developers 1746254Sgblack@eecs.umich.edu// Shift Rm by Rs 1756254Sgblack@eecs.umich.eduint32_t 1767148Sgblack@eecs.umich.eduArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt, 1777094Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const 1786254Sgblack@eecs.umich.edu{ 1796254Sgblack@eecs.umich.edu enum ArmShiftType shiftType; 1806254Sgblack@eecs.umich.edu shiftType = (enum ArmShiftType) type; 1816254Sgblack@eecs.umich.edu 1826254Sgblack@eecs.umich.edu switch (shiftType) 1836254Sgblack@eecs.umich.edu { 1846255Sgblack@eecs.umich.edu case LSL: 1856255Sgblack@eecs.umich.edu if (shamt >= 32) 1866255Sgblack@eecs.umich.edu return 0; 1876255Sgblack@eecs.umich.edu else 1886255Sgblack@eecs.umich.edu return base << shamt; 1896255Sgblack@eecs.umich.edu case LSR: 1906255Sgblack@eecs.umich.edu if (shamt >= 32) 1916255Sgblack@eecs.umich.edu return 0; 1926255Sgblack@eecs.umich.edu else 1936255Sgblack@eecs.umich.edu return base >> shamt; 1946255Sgblack@eecs.umich.edu case ASR: 1956255Sgblack@eecs.umich.edu if (shamt >= 32) 1967182Sgblack@eecs.umich.edu return (base >> 31) | -((base & (1 << 31)) >> 31); 1976255Sgblack@eecs.umich.edu else 1987182Sgblack@eecs.umich.edu return (base >> shamt) | -((base & (1 << 31)) >> shamt); 1996255Sgblack@eecs.umich.edu case ROR: 2006255Sgblack@eecs.umich.edu shamt = shamt & 0x1f; 2016255Sgblack@eecs.umich.edu if (shamt == 0) 2026255Sgblack@eecs.umich.edu return base; 2036255Sgblack@eecs.umich.edu else 2046255Sgblack@eecs.umich.edu return (base << (32 - shamt)) | (base >> shamt); 2056255Sgblack@eecs.umich.edu default: 2066712Snate@binkert.org ccprintf(std::cerr, "Unhandled shift type\n"); 2076255Sgblack@eecs.umich.edu exit(1); 2086255Sgblack@eecs.umich.edu break; 2096254Sgblack@eecs.umich.edu } 2106254Sgblack@eecs.umich.edu return 0; 2116254Sgblack@eecs.umich.edu} 2126254Sgblack@eecs.umich.edu 2136254Sgblack@eecs.umich.edu 2146254Sgblack@eecs.umich.edu// Generate C for a shift by immediate 2156255Sgblack@eecs.umich.edubool 2167148Sgblack@eecs.umich.eduArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt, 2177094Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const 2186254Sgblack@eecs.umich.edu{ 2196254Sgblack@eecs.umich.edu enum ArmShiftType shiftType; 2206254Sgblack@eecs.umich.edu shiftType = (enum ArmShiftType) type; 2216254Sgblack@eecs.umich.edu 2226254Sgblack@eecs.umich.edu switch (shiftType) 2236254Sgblack@eecs.umich.edu { 2246255Sgblack@eecs.umich.edu case LSL: 2256255Sgblack@eecs.umich.edu if (shamt == 0) 2266255Sgblack@eecs.umich.edu return cfval; 2276255Sgblack@eecs.umich.edu else 2286254Sgblack@eecs.umich.edu return (base >> (32 - shamt)) & 1; 2296255Sgblack@eecs.umich.edu case LSR: 2306255Sgblack@eecs.umich.edu if (shamt == 0) 2316255Sgblack@eecs.umich.edu return (base >> 31); 2326255Sgblack@eecs.umich.edu else 2336255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2346255Sgblack@eecs.umich.edu case ASR: 2356255Sgblack@eecs.umich.edu if (shamt == 0) 2366255Sgblack@eecs.umich.edu return (base >> 31); 2376255Sgblack@eecs.umich.edu else 2386255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2396255Sgblack@eecs.umich.edu case ROR: 2406255Sgblack@eecs.umich.edu shamt = shamt & 0x1f; 2416255Sgblack@eecs.umich.edu if (shamt == 0) 2426255Sgblack@eecs.umich.edu return (base & 1); // RRX 2436255Sgblack@eecs.umich.edu else 2446255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2456255Sgblack@eecs.umich.edu default: 2466712Snate@binkert.org ccprintf(std::cerr, "Unhandled shift type\n"); 2476255Sgblack@eecs.umich.edu exit(1); 2486255Sgblack@eecs.umich.edu break; 2496254Sgblack@eecs.umich.edu } 2506254Sgblack@eecs.umich.edu return 0; 2516254Sgblack@eecs.umich.edu} 2526254Sgblack@eecs.umich.edu 2536254Sgblack@eecs.umich.edu 2546254Sgblack@eecs.umich.edu// Generate C for a shift by Rs 2556255Sgblack@eecs.umich.edubool 2567148Sgblack@eecs.umich.eduArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt, 2577094Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const 2586254Sgblack@eecs.umich.edu{ 2596254Sgblack@eecs.umich.edu enum ArmShiftType shiftType; 2606254Sgblack@eecs.umich.edu shiftType = (enum ArmShiftType) type; 2616254Sgblack@eecs.umich.edu 2626255Sgblack@eecs.umich.edu if (shamt == 0) 2636255Sgblack@eecs.umich.edu return cfval; 2646255Sgblack@eecs.umich.edu 2656254Sgblack@eecs.umich.edu switch (shiftType) 2666254Sgblack@eecs.umich.edu { 2676255Sgblack@eecs.umich.edu case LSL: 2686255Sgblack@eecs.umich.edu if (shamt > 32) 2696255Sgblack@eecs.umich.edu return 0; 2706255Sgblack@eecs.umich.edu else 2716255Sgblack@eecs.umich.edu return (base >> (32 - shamt)) & 1; 2726255Sgblack@eecs.umich.edu case LSR: 2736255Sgblack@eecs.umich.edu if (shamt > 32) 2746255Sgblack@eecs.umich.edu return 0; 2756255Sgblack@eecs.umich.edu else 2766255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2776255Sgblack@eecs.umich.edu case ASR: 2786255Sgblack@eecs.umich.edu if (shamt > 32) 2796255Sgblack@eecs.umich.edu shamt = 32; 2806255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2816255Sgblack@eecs.umich.edu case ROR: 2826255Sgblack@eecs.umich.edu shamt = shamt & 0x1f; 2836255Sgblack@eecs.umich.edu if (shamt == 0) 2846255Sgblack@eecs.umich.edu shamt = 32; 2856255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2866255Sgblack@eecs.umich.edu default: 2876712Snate@binkert.org ccprintf(std::cerr, "Unhandled shift type\n"); 2886255Sgblack@eecs.umich.edu exit(1); 2896255Sgblack@eecs.umich.edu break; 2906254Sgblack@eecs.umich.edu } 2916254Sgblack@eecs.umich.edu return 0; 2926254Sgblack@eecs.umich.edu} 2936254Sgblack@eecs.umich.edu 2946254Sgblack@eecs.umich.edu 2956254Sgblack@eecs.umich.eduvoid 2967148Sgblack@eecs.umich.eduArmStaticInst::printReg(std::ostream &os, int reg) const 2976253Sgblack@eecs.umich.edu{ 2989913Ssteve.reinhardt@amd.com RegIndex rel_reg; 2999913Ssteve.reinhardt@amd.com 3009913Ssteve.reinhardt@amd.com switch (regIdxToClass(reg, &rel_reg)) { 3019913Ssteve.reinhardt@amd.com case IntRegClass: 30210037SARM gem5 Developers if (aarch64) { 30310037SARM gem5 Developers if (reg == INTREG_UREG0) 30410037SARM gem5 Developers ccprintf(os, "ureg0"); 30510037SARM gem5 Developers else if (reg == INTREG_SPX) 30610037SARM gem5 Developers ccprintf(os, "%s%s", (intWidth == 32) ? "w" : "", "sp"); 30710037SARM gem5 Developers else if (reg == INTREG_X31) 30810037SARM gem5 Developers ccprintf(os, "%szr", (intWidth == 32) ? "w" : "x"); 30910037SARM gem5 Developers else 31010037SARM gem5 Developers ccprintf(os, "%s%d", (intWidth == 32) ? "w" : "x", reg); 31110037SARM gem5 Developers } else { 31210037SARM gem5 Developers switch (rel_reg) { 31310037SARM gem5 Developers case PCReg: 31410037SARM gem5 Developers ccprintf(os, "pc"); 31510037SARM gem5 Developers break; 31610037SARM gem5 Developers case StackPointerReg: 31710037SARM gem5 Developers ccprintf(os, "sp"); 31810037SARM gem5 Developers break; 31910037SARM gem5 Developers case FramePointerReg: 32010037SARM gem5 Developers ccprintf(os, "fp"); 32110037SARM gem5 Developers break; 32210037SARM gem5 Developers case ReturnAddressReg: 32310037SARM gem5 Developers ccprintf(os, "lr"); 32410037SARM gem5 Developers break; 32510037SARM gem5 Developers default: 32610037SARM gem5 Developers ccprintf(os, "r%d", reg); 32710037SARM gem5 Developers break; 32810037SARM gem5 Developers } 3296261Sgblack@eecs.umich.edu } 3309913Ssteve.reinhardt@amd.com break; 3319913Ssteve.reinhardt@amd.com case FloatRegClass: 3329913Ssteve.reinhardt@amd.com ccprintf(os, "f%d", rel_reg); 3339913Ssteve.reinhardt@amd.com break; 3349913Ssteve.reinhardt@amd.com case MiscRegClass: 3359913Ssteve.reinhardt@amd.com assert(rel_reg < NUM_MISCREGS); 3369913Ssteve.reinhardt@amd.com ccprintf(os, "%s", ArmISA::miscRegName[rel_reg]); 3379913Ssteve.reinhardt@amd.com break; 3389920Syasuko.eckert@amd.com case CCRegClass: 33910338SCurtis.Dunham@arm.com ccprintf(os, "cc_%s", ArmISA::ccRegName[rel_reg]); 34010338SCurtis.Dunham@arm.com break; 3416253Sgblack@eecs.umich.edu } 3426253Sgblack@eecs.umich.edu} 3436253Sgblack@eecs.umich.edu 3446262Sgblack@eecs.umich.eduvoid 3457148Sgblack@eecs.umich.eduArmStaticInst::printMnemonic(std::ostream &os, 3466262Sgblack@eecs.umich.edu const std::string &suffix, 34710037SARM gem5 Developers bool withPred, 34810037SARM gem5 Developers bool withCond64, 34910037SARM gem5 Developers ConditionCode cond64) const 3506262Sgblack@eecs.umich.edu{ 3516262Sgblack@eecs.umich.edu os << " " << mnemonic; 35210037SARM gem5 Developers if (withPred && !aarch64) { 35310037SARM gem5 Developers printCondition(os, machInst.condCode); 3547122Sgblack@eecs.umich.edu os << suffix; 35510037SARM gem5 Developers } else if (withCond64) { 35610037SARM gem5 Developers os << "."; 35710037SARM gem5 Developers printCondition(os, cond64); 35810037SARM gem5 Developers os << suffix; 35910037SARM gem5 Developers } 36010037SARM gem5 Developers if (machInst.bigThumb) 36110037SARM gem5 Developers os << ".w"; 36210037SARM gem5 Developers os << " "; 36310037SARM gem5 Developers} 36410037SARM gem5 Developers 36510037SARM gem5 Developersvoid 36610037SARM gem5 DevelopersArmStaticInst::printTarget(std::ostream &os, Addr target, 36710037SARM gem5 Developers const SymbolTable *symtab) const 36810037SARM gem5 Developers{ 36910037SARM gem5 Developers Addr symbolAddr; 37010037SARM gem5 Developers std::string symbol; 37110037SARM gem5 Developers 37210037SARM gem5 Developers if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) { 37310037SARM gem5 Developers ccprintf(os, "<%s", symbol); 37410037SARM gem5 Developers if (symbolAddr != target) 37510037SARM gem5 Developers ccprintf(os, "+%d>", target - symbolAddr); 37610037SARM gem5 Developers else 37710037SARM gem5 Developers ccprintf(os, ">"); 37810037SARM gem5 Developers } else { 37910037SARM gem5 Developers ccprintf(os, "%#x", target); 38010037SARM gem5 Developers } 38110037SARM gem5 Developers} 38210037SARM gem5 Developers 38310037SARM gem5 Developersvoid 38410037SARM gem5 DevelopersArmStaticInst::printCondition(std::ostream &os, 38510037SARM gem5 Developers unsigned code, 38610037SARM gem5 Developers bool noImplicit) const 38710037SARM gem5 Developers{ 38810037SARM gem5 Developers switch (code) { 38910037SARM gem5 Developers case COND_EQ: 39010037SARM gem5 Developers os << "eq"; 39110037SARM gem5 Developers break; 39210037SARM gem5 Developers case COND_NE: 39310037SARM gem5 Developers os << "ne"; 39410037SARM gem5 Developers break; 39510037SARM gem5 Developers case COND_CS: 39610037SARM gem5 Developers os << "cs"; 39710037SARM gem5 Developers break; 39810037SARM gem5 Developers case COND_CC: 39910037SARM gem5 Developers os << "cc"; 40010037SARM gem5 Developers break; 40110037SARM gem5 Developers case COND_MI: 40210037SARM gem5 Developers os << "mi"; 40310037SARM gem5 Developers break; 40410037SARM gem5 Developers case COND_PL: 40510037SARM gem5 Developers os << "pl"; 40610037SARM gem5 Developers break; 40710037SARM gem5 Developers case COND_VS: 40810037SARM gem5 Developers os << "vs"; 40910037SARM gem5 Developers break; 41010037SARM gem5 Developers case COND_VC: 41110037SARM gem5 Developers os << "vc"; 41210037SARM gem5 Developers break; 41310037SARM gem5 Developers case COND_HI: 41410037SARM gem5 Developers os << "hi"; 41510037SARM gem5 Developers break; 41610037SARM gem5 Developers case COND_LS: 41710037SARM gem5 Developers os << "ls"; 41810037SARM gem5 Developers break; 41910037SARM gem5 Developers case COND_GE: 42010037SARM gem5 Developers os << "ge"; 42110037SARM gem5 Developers break; 42210037SARM gem5 Developers case COND_LT: 42310037SARM gem5 Developers os << "lt"; 42410037SARM gem5 Developers break; 42510037SARM gem5 Developers case COND_GT: 42610037SARM gem5 Developers os << "gt"; 42710037SARM gem5 Developers break; 42810037SARM gem5 Developers case COND_LE: 42910037SARM gem5 Developers os << "le"; 43010037SARM gem5 Developers break; 43110037SARM gem5 Developers case COND_AL: 43210037SARM gem5 Developers // This one is implicit. 43310037SARM gem5 Developers if (noImplicit) 43410037SARM gem5 Developers os << "al"; 43510037SARM gem5 Developers break; 43610037SARM gem5 Developers case COND_UC: 43710037SARM gem5 Developers // Unconditional. 43810037SARM gem5 Developers if (noImplicit) 43910037SARM gem5 Developers os << "uc"; 44010037SARM gem5 Developers break; 44110037SARM gem5 Developers default: 44210037SARM gem5 Developers panic("Unrecognized condition code %d.\n", code); 4436262Sgblack@eecs.umich.edu } 4446262Sgblack@eecs.umich.edu} 4456262Sgblack@eecs.umich.edu 4466263Sgblack@eecs.umich.eduvoid 4477148Sgblack@eecs.umich.eduArmStaticInst::printMemSymbol(std::ostream &os, 4486263Sgblack@eecs.umich.edu const SymbolTable *symtab, 4496263Sgblack@eecs.umich.edu const std::string &prefix, 4506263Sgblack@eecs.umich.edu const Addr addr, 4516263Sgblack@eecs.umich.edu const std::string &suffix) const 4526263Sgblack@eecs.umich.edu{ 4536263Sgblack@eecs.umich.edu Addr symbolAddr; 4546263Sgblack@eecs.umich.edu std::string symbol; 4556263Sgblack@eecs.umich.edu if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) { 4566263Sgblack@eecs.umich.edu ccprintf(os, "%s%s", prefix, symbol); 4576263Sgblack@eecs.umich.edu if (symbolAddr != addr) 4586263Sgblack@eecs.umich.edu ccprintf(os, "+%d", addr - symbolAddr); 4596263Sgblack@eecs.umich.edu ccprintf(os, suffix); 4606263Sgblack@eecs.umich.edu } 4616263Sgblack@eecs.umich.edu} 4626263Sgblack@eecs.umich.edu 4636264Sgblack@eecs.umich.eduvoid 4647148Sgblack@eecs.umich.eduArmStaticInst::printShiftOperand(std::ostream &os, 4657142Sgblack@eecs.umich.edu IntRegIndex rm, 4667142Sgblack@eecs.umich.edu bool immShift, 4677142Sgblack@eecs.umich.edu uint32_t shiftAmt, 4687142Sgblack@eecs.umich.edu IntRegIndex rs, 4697142Sgblack@eecs.umich.edu ArmShiftType type) const 4706264Sgblack@eecs.umich.edu{ 4717142Sgblack@eecs.umich.edu bool firstOp = false; 4726264Sgblack@eecs.umich.edu 4737142Sgblack@eecs.umich.edu if (rm != INTREG_ZERO) { 4747142Sgblack@eecs.umich.edu printReg(os, rm); 4757142Sgblack@eecs.umich.edu } 4767142Sgblack@eecs.umich.edu 4776306Sgblack@eecs.umich.edu bool done = false; 4786264Sgblack@eecs.umich.edu 4796306Sgblack@eecs.umich.edu if ((type == LSR || type == ASR) && immShift && shiftAmt == 0) 4806306Sgblack@eecs.umich.edu shiftAmt = 32; 4816264Sgblack@eecs.umich.edu 4826306Sgblack@eecs.umich.edu switch (type) { 4836306Sgblack@eecs.umich.edu case LSL: 4846306Sgblack@eecs.umich.edu if (immShift && shiftAmt == 0) { 4856306Sgblack@eecs.umich.edu done = true; 4866264Sgblack@eecs.umich.edu break; 4876306Sgblack@eecs.umich.edu } 4887142Sgblack@eecs.umich.edu if (!firstOp) 4897142Sgblack@eecs.umich.edu os << ", "; 4907142Sgblack@eecs.umich.edu os << "LSL"; 4916306Sgblack@eecs.umich.edu break; 4926306Sgblack@eecs.umich.edu case LSR: 4937142Sgblack@eecs.umich.edu if (!firstOp) 4947142Sgblack@eecs.umich.edu os << ", "; 4957142Sgblack@eecs.umich.edu os << "LSR"; 4966306Sgblack@eecs.umich.edu break; 4976306Sgblack@eecs.umich.edu case ASR: 4987142Sgblack@eecs.umich.edu if (!firstOp) 4997142Sgblack@eecs.umich.edu os << ", "; 5007142Sgblack@eecs.umich.edu os << "ASR"; 5016306Sgblack@eecs.umich.edu break; 5026306Sgblack@eecs.umich.edu case ROR: 5036306Sgblack@eecs.umich.edu if (immShift && shiftAmt == 0) { 5047142Sgblack@eecs.umich.edu if (!firstOp) 5057142Sgblack@eecs.umich.edu os << ", "; 5067142Sgblack@eecs.umich.edu os << "RRX"; 5076306Sgblack@eecs.umich.edu done = true; 5086264Sgblack@eecs.umich.edu break; 5096264Sgblack@eecs.umich.edu } 5107142Sgblack@eecs.umich.edu if (!firstOp) 5117142Sgblack@eecs.umich.edu os << ", "; 5127142Sgblack@eecs.umich.edu os << "ROR"; 5136306Sgblack@eecs.umich.edu break; 5146306Sgblack@eecs.umich.edu default: 5156306Sgblack@eecs.umich.edu panic("Tried to disassemble unrecognized shift type.\n"); 5166306Sgblack@eecs.umich.edu } 5176306Sgblack@eecs.umich.edu if (!done) { 5187142Sgblack@eecs.umich.edu if (!firstOp) 5197142Sgblack@eecs.umich.edu os << " "; 5206306Sgblack@eecs.umich.edu if (immShift) 5216306Sgblack@eecs.umich.edu os << "#" << shiftAmt; 5226306Sgblack@eecs.umich.edu else 5237142Sgblack@eecs.umich.edu printReg(os, rs); 5246264Sgblack@eecs.umich.edu } 5256264Sgblack@eecs.umich.edu} 5266264Sgblack@eecs.umich.edu 5276264Sgblack@eecs.umich.eduvoid 52810037SARM gem5 DevelopersArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os, 52910037SARM gem5 Developers IntRegIndex rm, ArmExtendType type, 53010037SARM gem5 Developers int64_t shiftAmt) const 53110037SARM gem5 Developers{ 53210037SARM gem5 Developers if (!firstOperand) 53310037SARM gem5 Developers ccprintf(os, ", "); 53410037SARM gem5 Developers printReg(os, rm); 53510037SARM gem5 Developers if (type == UXTX && shiftAmt == 0) 53610037SARM gem5 Developers return; 53710037SARM gem5 Developers switch (type) { 53810037SARM gem5 Developers case UXTB: ccprintf(os, ", UXTB"); 53910037SARM gem5 Developers break; 54010037SARM gem5 Developers case UXTH: ccprintf(os, ", UXTH"); 54110037SARM gem5 Developers break; 54210037SARM gem5 Developers case UXTW: ccprintf(os, ", UXTW"); 54310037SARM gem5 Developers break; 54410037SARM gem5 Developers case UXTX: ccprintf(os, ", LSL"); 54510037SARM gem5 Developers break; 54610037SARM gem5 Developers case SXTB: ccprintf(os, ", SXTB"); 54710037SARM gem5 Developers break; 54810037SARM gem5 Developers case SXTH: ccprintf(os, ", SXTH"); 54910037SARM gem5 Developers break; 55010037SARM gem5 Developers case SXTW: ccprintf(os, ", SXTW"); 55110037SARM gem5 Developers break; 55210037SARM gem5 Developers case SXTX: ccprintf(os, ", SXTW"); 55310037SARM gem5 Developers break; 55410037SARM gem5 Developers } 55510037SARM gem5 Developers if (type == UXTX || shiftAmt) 55610037SARM gem5 Developers ccprintf(os, " #%d", shiftAmt); 55710037SARM gem5 Developers} 55810037SARM gem5 Developers 55910037SARM gem5 Developersvoid 5607148Sgblack@eecs.umich.eduArmStaticInst::printDataInst(std::ostream &os, bool withImm, 5617142Sgblack@eecs.umich.edu bool immShift, bool s, IntRegIndex rd, IntRegIndex rn, 5627142Sgblack@eecs.umich.edu IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt, 56311371Snathanael.premillieu@arm.com ArmShiftType type, uint64_t imm) const 5646264Sgblack@eecs.umich.edu{ 5657142Sgblack@eecs.umich.edu printMnemonic(os, s ? "s" : ""); 5666264Sgblack@eecs.umich.edu bool firstOp = true; 5676264Sgblack@eecs.umich.edu 5686264Sgblack@eecs.umich.edu // Destination 5697142Sgblack@eecs.umich.edu if (rd != INTREG_ZERO) { 5706264Sgblack@eecs.umich.edu firstOp = false; 5717142Sgblack@eecs.umich.edu printReg(os, rd); 5726264Sgblack@eecs.umich.edu } 5736264Sgblack@eecs.umich.edu 5746264Sgblack@eecs.umich.edu // Source 1. 5757142Sgblack@eecs.umich.edu if (rn != INTREG_ZERO) { 5766264Sgblack@eecs.umich.edu if (!firstOp) 5776264Sgblack@eecs.umich.edu os << ", "; 5786264Sgblack@eecs.umich.edu firstOp = false; 5797142Sgblack@eecs.umich.edu printReg(os, rn); 5806264Sgblack@eecs.umich.edu } 5816264Sgblack@eecs.umich.edu 5826264Sgblack@eecs.umich.edu if (!firstOp) 5836264Sgblack@eecs.umich.edu os << ", "; 5846306Sgblack@eecs.umich.edu if (withImm) { 58511371Snathanael.premillieu@arm.com ccprintf(os, "#%ld", imm); 5866306Sgblack@eecs.umich.edu } else { 5877142Sgblack@eecs.umich.edu printShiftOperand(os, rm, immShift, shiftAmt, rs, type); 5886306Sgblack@eecs.umich.edu } 5896264Sgblack@eecs.umich.edu} 5906264Sgblack@eecs.umich.edu 5916254Sgblack@eecs.umich.edustd::string 5927148Sgblack@eecs.umich.eduArmStaticInst::generateDisassembly(Addr pc, 5936254Sgblack@eecs.umich.edu const SymbolTable *symtab) const 5946253Sgblack@eecs.umich.edu{ 5956253Sgblack@eecs.umich.edu std::stringstream ss; 5966262Sgblack@eecs.umich.edu printMnemonic(ss); 5976253Sgblack@eecs.umich.edu return ss.str(); 5986253Sgblack@eecs.umich.edu} 59911513Sandreas.sandberg@arm.com 60011513Sandreas.sandberg@arm.com 60111513Sandreas.sandberg@arm.comFault 60211513Sandreas.sandberg@arm.comArmStaticInst::advSIMDFPAccessTrap64(ExceptionLevel el) const 60311513Sandreas.sandberg@arm.com{ 60411513Sandreas.sandberg@arm.com switch (el) { 60511513Sandreas.sandberg@arm.com case EL1: 60611513Sandreas.sandberg@arm.com return std::make_shared<SupervisorTrap>(machInst, 0x1E00000, 60711513Sandreas.sandberg@arm.com EC_TRAPPED_SIMD_FP); 60811513Sandreas.sandberg@arm.com case EL2: 60911513Sandreas.sandberg@arm.com return std::make_shared<HypervisorTrap>(machInst, 0x1E00000, 61011513Sandreas.sandberg@arm.com EC_TRAPPED_SIMD_FP); 61111513Sandreas.sandberg@arm.com case EL3: 61211513Sandreas.sandberg@arm.com return std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000, 61311513Sandreas.sandberg@arm.com EC_TRAPPED_SIMD_FP); 61411513Sandreas.sandberg@arm.com 61511513Sandreas.sandberg@arm.com default: 61611513Sandreas.sandberg@arm.com panic("Illegal EL in advSIMDFPAccessTrap64\n"); 61711513Sandreas.sandberg@arm.com } 6186253Sgblack@eecs.umich.edu} 61911513Sandreas.sandberg@arm.com 62011513Sandreas.sandberg@arm.com 62111513Sandreas.sandberg@arm.comFault 62211513Sandreas.sandberg@arm.comArmStaticInst::checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const 62311513Sandreas.sandberg@arm.com{ 62411513Sandreas.sandberg@arm.com const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el; 62511513Sandreas.sandberg@arm.com 62611513Sandreas.sandberg@arm.com if (ArmSystem::haveVirtualization(tc) && el <= EL2) { 62711513Sandreas.sandberg@arm.com HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL2); 62811513Sandreas.sandberg@arm.com if (cptrEnCheck.tfp) 62911513Sandreas.sandberg@arm.com return advSIMDFPAccessTrap64(EL2); 63011513Sandreas.sandberg@arm.com } 63111513Sandreas.sandberg@arm.com 63211513Sandreas.sandberg@arm.com if (ArmSystem::haveSecurity(tc)) { 63311513Sandreas.sandberg@arm.com HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3); 63411513Sandreas.sandberg@arm.com if (cptrEnCheck.tfp) 63511513Sandreas.sandberg@arm.com return advSIMDFPAccessTrap64(EL3); 63611513Sandreas.sandberg@arm.com } 63711513Sandreas.sandberg@arm.com 63811513Sandreas.sandberg@arm.com return NoFault; 63911513Sandreas.sandberg@arm.com} 64011513Sandreas.sandberg@arm.com 64111513Sandreas.sandberg@arm.comFault 64211513Sandreas.sandberg@arm.comArmStaticInst::checkFPAdvSIMDEnabled64(ThreadContext *tc, 64311513Sandreas.sandberg@arm.com CPSR cpsr, CPACR cpacr) const 64411513Sandreas.sandberg@arm.com{ 64511513Sandreas.sandberg@arm.com const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el; 64611513Sandreas.sandberg@arm.com if ((el == EL0 && cpacr.fpen != 0x3) || 64711513Sandreas.sandberg@arm.com (el == EL1 && !(cpacr.fpen & 0x1))) 64811513Sandreas.sandberg@arm.com return advSIMDFPAccessTrap64(EL1); 64911513Sandreas.sandberg@arm.com 65011513Sandreas.sandberg@arm.com return checkFPAdvSIMDTrap64(tc, cpsr); 65111513Sandreas.sandberg@arm.com} 65211513Sandreas.sandberg@arm.com 65311513Sandreas.sandberg@arm.comFault 65411513Sandreas.sandberg@arm.comArmStaticInst::checkAdvSIMDOrFPEnabled32(ThreadContext *tc, 65511513Sandreas.sandberg@arm.com CPSR cpsr, CPACR cpacr, 65611513Sandreas.sandberg@arm.com NSACR nsacr, FPEXC fpexc, 65711513Sandreas.sandberg@arm.com bool fpexc_check, bool advsimd) const 65811513Sandreas.sandberg@arm.com{ 65911513Sandreas.sandberg@arm.com const bool have_virtualization = ArmSystem::haveVirtualization(tc); 66011513Sandreas.sandberg@arm.com const bool have_security = ArmSystem::haveSecurity(tc); 66111513Sandreas.sandberg@arm.com const bool is_secure = inSecureState(tc); 66211513Sandreas.sandberg@arm.com const ExceptionLevel cur_el = opModeToEL(currOpMode(tc)); 66311513Sandreas.sandberg@arm.com 66411513Sandreas.sandberg@arm.com if (cur_el == EL0 && ELIs64(tc, EL1)) 66511513Sandreas.sandberg@arm.com return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr); 66611513Sandreas.sandberg@arm.com 66711513Sandreas.sandberg@arm.com uint8_t cpacr_cp10 = cpacr.cp10; 66811513Sandreas.sandberg@arm.com bool cpacr_asedis = cpacr.asedis; 66911513Sandreas.sandberg@arm.com 67011513Sandreas.sandberg@arm.com if (have_security && !ELIs64(tc, EL3) && !is_secure) { 67111513Sandreas.sandberg@arm.com if (nsacr.nsasedis) 67211513Sandreas.sandberg@arm.com cpacr_asedis = true; 67311513Sandreas.sandberg@arm.com if (nsacr.cp10 == 0) 67411513Sandreas.sandberg@arm.com cpacr_cp10 = 0; 67511513Sandreas.sandberg@arm.com } 67611513Sandreas.sandberg@arm.com 67711513Sandreas.sandberg@arm.com if (cur_el != EL2) { 67811513Sandreas.sandberg@arm.com if (advsimd && cpacr_asedis) 67911513Sandreas.sandberg@arm.com return disabledFault(); 68011513Sandreas.sandberg@arm.com 68111513Sandreas.sandberg@arm.com if ((cur_el == EL0 && cpacr_cp10 != 0x3) || 68211513Sandreas.sandberg@arm.com (cur_el != EL0 && !(cpacr_cp10 & 0x1))) 68311513Sandreas.sandberg@arm.com return disabledFault(); 68411513Sandreas.sandberg@arm.com } 68511513Sandreas.sandberg@arm.com 68611513Sandreas.sandberg@arm.com if (fpexc_check && !fpexc.en) 68711513Sandreas.sandberg@arm.com return disabledFault(); 68811513Sandreas.sandberg@arm.com 68911513Sandreas.sandberg@arm.com // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap -- 69011513Sandreas.sandberg@arm.com 69111513Sandreas.sandberg@arm.com if (have_virtualization && !is_secure && ELIs64(tc, EL2)) 69211513Sandreas.sandberg@arm.com return checkFPAdvSIMDTrap64(tc, cpsr); 69311513Sandreas.sandberg@arm.com 69411513Sandreas.sandberg@arm.com if (have_virtualization && !is_secure) { 69511513Sandreas.sandberg@arm.com HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR); 69611513Sandreas.sandberg@arm.com bool hcptr_cp10 = hcptr.tcp10; 69711513Sandreas.sandberg@arm.com bool hcptr_tase = hcptr.tase; 69811513Sandreas.sandberg@arm.com 69911513Sandreas.sandberg@arm.com if (have_security && !ELIs64(tc, EL3) && !is_secure) { 70011513Sandreas.sandberg@arm.com if (nsacr.nsasedis) 70111513Sandreas.sandberg@arm.com hcptr_tase = true; 70211513Sandreas.sandberg@arm.com if (nsacr.cp10) 70311513Sandreas.sandberg@arm.com hcptr_cp10 = true; 70411513Sandreas.sandberg@arm.com } 70511513Sandreas.sandberg@arm.com 70611513Sandreas.sandberg@arm.com if ((advsimd && hcptr_tase) || hcptr_cp10) { 70711513Sandreas.sandberg@arm.com const uint32_t iss = advsimd ? (1 << 5) : 0xA; 70811513Sandreas.sandberg@arm.com if (cur_el == EL2) { 70911513Sandreas.sandberg@arm.com return std::make_shared<UndefinedInstruction>( 71011513Sandreas.sandberg@arm.com machInst, iss, 71111513Sandreas.sandberg@arm.com EC_TRAPPED_HCPTR, mnemonic); 71211513Sandreas.sandberg@arm.com } else { 71311513Sandreas.sandberg@arm.com return std::make_shared<HypervisorTrap>( 71411513Sandreas.sandberg@arm.com machInst, iss, 71511513Sandreas.sandberg@arm.com EC_TRAPPED_HCPTR); 71611513Sandreas.sandberg@arm.com } 71711513Sandreas.sandberg@arm.com 71811513Sandreas.sandberg@arm.com } 71911513Sandreas.sandberg@arm.com } 72011513Sandreas.sandberg@arm.com 72111513Sandreas.sandberg@arm.com if (have_security && ELIs64(tc, EL3)) { 72211513Sandreas.sandberg@arm.com HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3); 72311513Sandreas.sandberg@arm.com if (cptrEnCheck.tfp) 72411513Sandreas.sandberg@arm.com return advSIMDFPAccessTrap64(EL3); 72511513Sandreas.sandberg@arm.com } 72611513Sandreas.sandberg@arm.com 72711513Sandreas.sandberg@arm.com return NoFault; 72811513Sandreas.sandberg@arm.com} 72911513Sandreas.sandberg@arm.com 73011513Sandreas.sandberg@arm.com 73111514Sandreas.sandberg@arm.comstatic uint8_t 73211514Sandreas.sandberg@arm.comgetRestoredITBits(ThreadContext *tc, CPSR spsr) 73311514Sandreas.sandberg@arm.com{ 73411514Sandreas.sandberg@arm.com // See: shared/functions/system/RestoredITBits in the ARM ARM 73511514Sandreas.sandberg@arm.com 73611514Sandreas.sandberg@arm.com const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode); 73711514Sandreas.sandberg@arm.com const uint8_t it = itState(spsr); 73811514Sandreas.sandberg@arm.com 73911514Sandreas.sandberg@arm.com if (!spsr.t || spsr.il) 74011514Sandreas.sandberg@arm.com return 0; 74111514Sandreas.sandberg@arm.com 74211514Sandreas.sandberg@arm.com // The IT bits are forced to zero when they are set to a reserved 74311514Sandreas.sandberg@arm.com // value. 74411514Sandreas.sandberg@arm.com if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0) 74511514Sandreas.sandberg@arm.com return 0; 74611514Sandreas.sandberg@arm.com 74711514Sandreas.sandberg@arm.com const bool itd = el == EL2 ? 74811514Sandreas.sandberg@arm.com ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd : 74911514Sandreas.sandberg@arm.com ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd; 75011514Sandreas.sandberg@arm.com 75111514Sandreas.sandberg@arm.com // The IT bits are forced to zero when returning to A32 state, or 75211514Sandreas.sandberg@arm.com // when returning to an EL with the ITD bit set to 1, and the IT 75311514Sandreas.sandberg@arm.com // bits are describing a multi-instruction block. 75411514Sandreas.sandberg@arm.com if (itd && bits(it, 2, 0) != 0) 75511514Sandreas.sandberg@arm.com return 0; 75611514Sandreas.sandberg@arm.com 75711514Sandreas.sandberg@arm.com return it; 75811513Sandreas.sandberg@arm.com} 75911514Sandreas.sandberg@arm.com 76011514Sandreas.sandberg@arm.comstatic bool 76111514Sandreas.sandberg@arm.comillegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr) 76211514Sandreas.sandberg@arm.com{ 76311514Sandreas.sandberg@arm.com const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode; 76411514Sandreas.sandberg@arm.com if (badMode(mode)) 76511514Sandreas.sandberg@arm.com return true; 76611514Sandreas.sandberg@arm.com 76711514Sandreas.sandberg@arm.com const OperatingMode cur_mode = (OperatingMode) (uint8_t)cpsr.mode; 76811514Sandreas.sandberg@arm.com const ExceptionLevel target_el = opModeToEL(mode); 76911514Sandreas.sandberg@arm.com if (target_el > opModeToEL(cur_mode)) 77011514Sandreas.sandberg@arm.com return true; 77111514Sandreas.sandberg@arm.com 77211514Sandreas.sandberg@arm.com if (target_el == EL3 && !ArmSystem::haveSecurity(tc)) 77311514Sandreas.sandberg@arm.com return true; 77411514Sandreas.sandberg@arm.com 77511514Sandreas.sandberg@arm.com if (target_el == EL2 && !ArmSystem::haveVirtualization(tc)) 77611514Sandreas.sandberg@arm.com return true; 77711514Sandreas.sandberg@arm.com 77811514Sandreas.sandberg@arm.com if (!spsr.width) { 77911514Sandreas.sandberg@arm.com // aarch64 78011514Sandreas.sandberg@arm.com if (!ArmSystem::highestELIs64(tc)) 78111514Sandreas.sandberg@arm.com return true; 78211514Sandreas.sandberg@arm.com 78311514Sandreas.sandberg@arm.com if (spsr & 0x2) 78411514Sandreas.sandberg@arm.com return true; 78511514Sandreas.sandberg@arm.com if (target_el == EL0 && spsr.sp) 78611514Sandreas.sandberg@arm.com return true; 78711514Sandreas.sandberg@arm.com if (target_el == EL2 && !((SCR)tc->readMiscReg(MISCREG_SCR_EL3)).ns) 78811514Sandreas.sandberg@arm.com return false; 78911514Sandreas.sandberg@arm.com } else { 79011514Sandreas.sandberg@arm.com return badMode32(mode); 79111514Sandreas.sandberg@arm.com } 79211514Sandreas.sandberg@arm.com 79311514Sandreas.sandberg@arm.com return false; 79411514Sandreas.sandberg@arm.com} 79511514Sandreas.sandberg@arm.com 79611514Sandreas.sandberg@arm.comCPSR 79711514Sandreas.sandberg@arm.comArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const 79811514Sandreas.sandberg@arm.com{ 79911514Sandreas.sandberg@arm.com CPSR new_cpsr = 0; 80011514Sandreas.sandberg@arm.com 80111514Sandreas.sandberg@arm.com // gem5 doesn't implement single-stepping, so force the SS bit to 80211514Sandreas.sandberg@arm.com // 0. 80311514Sandreas.sandberg@arm.com new_cpsr.ss = 0; 80411514Sandreas.sandberg@arm.com 80511514Sandreas.sandberg@arm.com if (illegalExceptionReturn(tc, cpsr, spsr)) { 80611514Sandreas.sandberg@arm.com new_cpsr.il = 1; 80711514Sandreas.sandberg@arm.com } else { 80811514Sandreas.sandberg@arm.com new_cpsr.il = spsr.il; 80911514Sandreas.sandberg@arm.com if (spsr.width && badMode32((OperatingMode)(uint8_t)spsr.mode)) { 81011514Sandreas.sandberg@arm.com new_cpsr.il = 1; 81111514Sandreas.sandberg@arm.com } else if (spsr.width) { 81211514Sandreas.sandberg@arm.com new_cpsr.mode = spsr.mode; 81311514Sandreas.sandberg@arm.com } else { 81411514Sandreas.sandberg@arm.com new_cpsr.el = spsr.el; 81511514Sandreas.sandberg@arm.com new_cpsr.sp = spsr.sp; 81611514Sandreas.sandberg@arm.com } 81711514Sandreas.sandberg@arm.com } 81811514Sandreas.sandberg@arm.com 81911514Sandreas.sandberg@arm.com new_cpsr.nz = spsr.nz; 82011514Sandreas.sandberg@arm.com new_cpsr.c = spsr.c; 82111514Sandreas.sandberg@arm.com new_cpsr.v = spsr.v; 82211514Sandreas.sandberg@arm.com if (new_cpsr.width) { 82311514Sandreas.sandberg@arm.com // aarch32 82411514Sandreas.sandberg@arm.com const ITSTATE it = getRestoredITBits(tc, spsr); 82511514Sandreas.sandberg@arm.com new_cpsr.q = spsr.q; 82611514Sandreas.sandberg@arm.com new_cpsr.ge = spsr.ge; 82711514Sandreas.sandberg@arm.com new_cpsr.e = spsr.e; 82811514Sandreas.sandberg@arm.com new_cpsr.aif = spsr.aif; 82911514Sandreas.sandberg@arm.com new_cpsr.t = spsr.t; 83011514Sandreas.sandberg@arm.com new_cpsr.it2 = it.top6; 83111514Sandreas.sandberg@arm.com new_cpsr.it1 = it.bottom2; 83211514Sandreas.sandberg@arm.com } else { 83311514Sandreas.sandberg@arm.com // aarch64 83411514Sandreas.sandberg@arm.com new_cpsr.daif = spsr.daif; 83511514Sandreas.sandberg@arm.com } 83611514Sandreas.sandberg@arm.com 83711514Sandreas.sandberg@arm.com return new_cpsr; 83811514Sandreas.sandberg@arm.com} 83911514Sandreas.sandberg@arm.com 84011514Sandreas.sandberg@arm.com 84111514Sandreas.sandberg@arm.com 84211514Sandreas.sandberg@arm.com} 843