static_inst.cc revision 12403
17094Sgblack@eecs.umich.edu/* 212403Sgiacomo.travaglini@arm.com * Copyright (c) 2010-2014, 2016-2017 ARM Limited 39913Ssteve.reinhardt@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 47094Sgblack@eecs.umich.edu * All rights reserved 57094Sgblack@eecs.umich.edu * 67094Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 77094Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 87094Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 97094Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 107094Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 117094Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 127094Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 137094Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 147094Sgblack@eecs.umich.edu * 157094Sgblack@eecs.umich.edu * Copyright (c) 2007-2008 The Florida State University 166253Sgblack@eecs.umich.edu * All rights reserved. 176253Sgblack@eecs.umich.edu * 186253Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 196253Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 206253Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 216253Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 226253Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 236253Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 246253Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 256253Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 266253Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 276253Sgblack@eecs.umich.edu * this software without specific prior written permission. 286253Sgblack@eecs.umich.edu * 296253Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 306253Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316253Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 326253Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 336253Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 346253Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 356253Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 366253Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 376253Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 386253Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 396253Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 406253Sgblack@eecs.umich.edu * 416253Sgblack@eecs.umich.edu * Authors: Stephen Hines 426253Sgblack@eecs.umich.edu */ 436253Sgblack@eecs.umich.edu 448229Snate@binkert.org#include "arch/arm/insts/static_inst.hh" 4511793Sbrandon.potter@amd.com 466759SAli.Saidi@ARM.com#include "arch/arm/faults.hh" 476255Sgblack@eecs.umich.edu#include "base/condcodes.hh" 486712Snate@binkert.org#include "base/cprintf.hh" 4911793Sbrandon.potter@amd.com#include "base/loader/symtab.hh" 509913Ssteve.reinhardt@amd.com#include "cpu/reg_class.hh" 516253Sgblack@eecs.umich.edu 526253Sgblack@eecs.umich.edunamespace ArmISA 536253Sgblack@eecs.umich.edu{ 546254Sgblack@eecs.umich.edu// Shift Rm by an immediate value 556254Sgblack@eecs.umich.eduint32_t 567148Sgblack@eecs.umich.eduArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt, 577094Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const 586254Sgblack@eecs.umich.edu{ 596255Sgblack@eecs.umich.edu assert(shamt < 32); 606255Sgblack@eecs.umich.edu ArmShiftType shiftType; 616255Sgblack@eecs.umich.edu shiftType = (ArmShiftType)type; 626254Sgblack@eecs.umich.edu 636254Sgblack@eecs.umich.edu switch (shiftType) 646254Sgblack@eecs.umich.edu { 656255Sgblack@eecs.umich.edu case LSL: 666255Sgblack@eecs.umich.edu return base << shamt; 676255Sgblack@eecs.umich.edu case LSR: 686255Sgblack@eecs.umich.edu if (shamt == 0) 696255Sgblack@eecs.umich.edu return 0; 706255Sgblack@eecs.umich.edu else 716255Sgblack@eecs.umich.edu return base >> shamt; 726255Sgblack@eecs.umich.edu case ASR: 736255Sgblack@eecs.umich.edu if (shamt == 0) 747182Sgblack@eecs.umich.edu return (base >> 31) | -((base & (1 << 31)) >> 31); 756255Sgblack@eecs.umich.edu else 767182Sgblack@eecs.umich.edu return (base >> shamt) | -((base & (1 << 31)) >> shamt); 776255Sgblack@eecs.umich.edu case ROR: 786255Sgblack@eecs.umich.edu if (shamt == 0) 796255Sgblack@eecs.umich.edu return (cfval << 31) | (base >> 1); // RRX 806255Sgblack@eecs.umich.edu else 816255Sgblack@eecs.umich.edu return (base << (32 - shamt)) | (base >> shamt); 826255Sgblack@eecs.umich.edu default: 836712Snate@binkert.org ccprintf(std::cerr, "Unhandled shift type\n"); 846255Sgblack@eecs.umich.edu exit(1); 856255Sgblack@eecs.umich.edu break; 866254Sgblack@eecs.umich.edu } 876254Sgblack@eecs.umich.edu return 0; 886254Sgblack@eecs.umich.edu} 896254Sgblack@eecs.umich.edu 9010037SARM gem5 Developersint64_t 9110037SARM gem5 DevelopersArmStaticInst::shiftReg64(uint64_t base, uint64_t shiftAmt, 9210037SARM gem5 Developers ArmShiftType type, uint8_t width) const 9310037SARM gem5 Developers{ 9410037SARM gem5 Developers shiftAmt = shiftAmt % width; 9510037SARM gem5 Developers ArmShiftType shiftType; 9610037SARM gem5 Developers shiftType = (ArmShiftType)type; 9710037SARM gem5 Developers 9810037SARM gem5 Developers switch (shiftType) 9910037SARM gem5 Developers { 10010037SARM gem5 Developers case LSL: 10110037SARM gem5 Developers return base << shiftAmt; 10210037SARM gem5 Developers case LSR: 10310037SARM gem5 Developers if (shiftAmt == 0) 10410037SARM gem5 Developers return base; 10510037SARM gem5 Developers else 10610037SARM gem5 Developers return (base & mask(width)) >> shiftAmt; 10710037SARM gem5 Developers case ASR: 10810037SARM gem5 Developers if (shiftAmt == 0) { 10910037SARM gem5 Developers return base; 11010037SARM gem5 Developers } else { 11110037SARM gem5 Developers int sign_bit = bits(base, intWidth - 1); 11210037SARM gem5 Developers base >>= shiftAmt; 11310037SARM gem5 Developers base = sign_bit ? (base | ~mask(intWidth - shiftAmt)) : base; 11410037SARM gem5 Developers return base & mask(intWidth); 11510037SARM gem5 Developers } 11610037SARM gem5 Developers case ROR: 11710037SARM gem5 Developers if (shiftAmt == 0) 11810037SARM gem5 Developers return base; 11910037SARM gem5 Developers else 12010037SARM gem5 Developers return (base << (width - shiftAmt)) | (base >> shiftAmt); 12110037SARM gem5 Developers default: 12210037SARM gem5 Developers ccprintf(std::cerr, "Unhandled shift type\n"); 12310037SARM gem5 Developers exit(1); 12410037SARM gem5 Developers break; 12510037SARM gem5 Developers } 12610037SARM gem5 Developers return 0; 12710037SARM gem5 Developers} 12810037SARM gem5 Developers 12910037SARM gem5 Developersint64_t 13010037SARM gem5 DevelopersArmStaticInst::extendReg64(uint64_t base, ArmExtendType type, 13110037SARM gem5 Developers uint64_t shiftAmt, uint8_t width) const 13210037SARM gem5 Developers{ 13310037SARM gem5 Developers bool sign_extend = false; 13410037SARM gem5 Developers int len = 0; 13510037SARM gem5 Developers switch (type) { 13610037SARM gem5 Developers case UXTB: 13710037SARM gem5 Developers len = 8; 13810037SARM gem5 Developers break; 13910037SARM gem5 Developers case UXTH: 14010037SARM gem5 Developers len = 16; 14110037SARM gem5 Developers break; 14210037SARM gem5 Developers case UXTW: 14310037SARM gem5 Developers len = 32; 14410037SARM gem5 Developers break; 14510037SARM gem5 Developers case UXTX: 14610037SARM gem5 Developers len = 64; 14710037SARM gem5 Developers break; 14810037SARM gem5 Developers case SXTB: 14910037SARM gem5 Developers len = 8; 15010037SARM gem5 Developers sign_extend = true; 15110037SARM gem5 Developers break; 15210037SARM gem5 Developers case SXTH: 15310037SARM gem5 Developers len = 16; 15410037SARM gem5 Developers sign_extend = true; 15510037SARM gem5 Developers break; 15610037SARM gem5 Developers case SXTW: 15710037SARM gem5 Developers len = 32; 15810037SARM gem5 Developers sign_extend = true; 15910037SARM gem5 Developers break; 16010037SARM gem5 Developers case SXTX: 16110037SARM gem5 Developers len = 64; 16210037SARM gem5 Developers sign_extend = true; 16310037SARM gem5 Developers break; 16410037SARM gem5 Developers } 16510037SARM gem5 Developers len = len <= width - shiftAmt ? len : width - shiftAmt; 16610037SARM gem5 Developers uint64_t tmp = (uint64_t) bits(base, len - 1, 0) << shiftAmt; 16710037SARM gem5 Developers if (sign_extend) { 16810037SARM gem5 Developers int sign_bit = bits(tmp, len + shiftAmt - 1); 16910037SARM gem5 Developers tmp = sign_bit ? (tmp | ~mask(len + shiftAmt)) : tmp; 17010037SARM gem5 Developers } 17110037SARM gem5 Developers return tmp & mask(width); 17210037SARM gem5 Developers} 17310037SARM gem5 Developers 1746254Sgblack@eecs.umich.edu// Shift Rm by Rs 1756254Sgblack@eecs.umich.eduint32_t 1767148Sgblack@eecs.umich.eduArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt, 1777094Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const 1786254Sgblack@eecs.umich.edu{ 1796254Sgblack@eecs.umich.edu enum ArmShiftType shiftType; 1806254Sgblack@eecs.umich.edu shiftType = (enum ArmShiftType) type; 1816254Sgblack@eecs.umich.edu 1826254Sgblack@eecs.umich.edu switch (shiftType) 1836254Sgblack@eecs.umich.edu { 1846255Sgblack@eecs.umich.edu case LSL: 1856255Sgblack@eecs.umich.edu if (shamt >= 32) 1866255Sgblack@eecs.umich.edu return 0; 1876255Sgblack@eecs.umich.edu else 1886255Sgblack@eecs.umich.edu return base << shamt; 1896255Sgblack@eecs.umich.edu case LSR: 1906255Sgblack@eecs.umich.edu if (shamt >= 32) 1916255Sgblack@eecs.umich.edu return 0; 1926255Sgblack@eecs.umich.edu else 1936255Sgblack@eecs.umich.edu return base >> shamt; 1946255Sgblack@eecs.umich.edu case ASR: 1956255Sgblack@eecs.umich.edu if (shamt >= 32) 1967182Sgblack@eecs.umich.edu return (base >> 31) | -((base & (1 << 31)) >> 31); 1976255Sgblack@eecs.umich.edu else 1987182Sgblack@eecs.umich.edu return (base >> shamt) | -((base & (1 << 31)) >> shamt); 1996255Sgblack@eecs.umich.edu case ROR: 2006255Sgblack@eecs.umich.edu shamt = shamt & 0x1f; 2016255Sgblack@eecs.umich.edu if (shamt == 0) 2026255Sgblack@eecs.umich.edu return base; 2036255Sgblack@eecs.umich.edu else 2046255Sgblack@eecs.umich.edu return (base << (32 - shamt)) | (base >> shamt); 2056255Sgblack@eecs.umich.edu default: 2066712Snate@binkert.org ccprintf(std::cerr, "Unhandled shift type\n"); 2076255Sgblack@eecs.umich.edu exit(1); 2086255Sgblack@eecs.umich.edu break; 2096254Sgblack@eecs.umich.edu } 2106254Sgblack@eecs.umich.edu return 0; 2116254Sgblack@eecs.umich.edu} 2126254Sgblack@eecs.umich.edu 2136254Sgblack@eecs.umich.edu 2146254Sgblack@eecs.umich.edu// Generate C for a shift by immediate 2156255Sgblack@eecs.umich.edubool 2167148Sgblack@eecs.umich.eduArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt, 2177094Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const 2186254Sgblack@eecs.umich.edu{ 2196254Sgblack@eecs.umich.edu enum ArmShiftType shiftType; 2206254Sgblack@eecs.umich.edu shiftType = (enum ArmShiftType) type; 2216254Sgblack@eecs.umich.edu 2226254Sgblack@eecs.umich.edu switch (shiftType) 2236254Sgblack@eecs.umich.edu { 2246255Sgblack@eecs.umich.edu case LSL: 2256255Sgblack@eecs.umich.edu if (shamt == 0) 2266255Sgblack@eecs.umich.edu return cfval; 2276255Sgblack@eecs.umich.edu else 2286254Sgblack@eecs.umich.edu return (base >> (32 - shamt)) & 1; 2296255Sgblack@eecs.umich.edu case LSR: 2306255Sgblack@eecs.umich.edu if (shamt == 0) 2316255Sgblack@eecs.umich.edu return (base >> 31); 2326255Sgblack@eecs.umich.edu else 2336255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2346255Sgblack@eecs.umich.edu case ASR: 2356255Sgblack@eecs.umich.edu if (shamt == 0) 2366255Sgblack@eecs.umich.edu return (base >> 31); 2376255Sgblack@eecs.umich.edu else 2386255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2396255Sgblack@eecs.umich.edu case ROR: 2406255Sgblack@eecs.umich.edu shamt = shamt & 0x1f; 2416255Sgblack@eecs.umich.edu if (shamt == 0) 2426255Sgblack@eecs.umich.edu return (base & 1); // RRX 2436255Sgblack@eecs.umich.edu else 2446255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2456255Sgblack@eecs.umich.edu default: 2466712Snate@binkert.org ccprintf(std::cerr, "Unhandled shift type\n"); 2476255Sgblack@eecs.umich.edu exit(1); 2486255Sgblack@eecs.umich.edu break; 2496254Sgblack@eecs.umich.edu } 2506254Sgblack@eecs.umich.edu return 0; 2516254Sgblack@eecs.umich.edu} 2526254Sgblack@eecs.umich.edu 2536254Sgblack@eecs.umich.edu 2546254Sgblack@eecs.umich.edu// Generate C for a shift by Rs 2556255Sgblack@eecs.umich.edubool 2567148Sgblack@eecs.umich.eduArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt, 2577094Sgblack@eecs.umich.edu uint32_t type, uint32_t cfval) const 2586254Sgblack@eecs.umich.edu{ 2596254Sgblack@eecs.umich.edu enum ArmShiftType shiftType; 2606254Sgblack@eecs.umich.edu shiftType = (enum ArmShiftType) type; 2616254Sgblack@eecs.umich.edu 2626255Sgblack@eecs.umich.edu if (shamt == 0) 2636255Sgblack@eecs.umich.edu return cfval; 2646255Sgblack@eecs.umich.edu 2656254Sgblack@eecs.umich.edu switch (shiftType) 2666254Sgblack@eecs.umich.edu { 2676255Sgblack@eecs.umich.edu case LSL: 2686255Sgblack@eecs.umich.edu if (shamt > 32) 2696255Sgblack@eecs.umich.edu return 0; 2706255Sgblack@eecs.umich.edu else 2716255Sgblack@eecs.umich.edu return (base >> (32 - shamt)) & 1; 2726255Sgblack@eecs.umich.edu case LSR: 2736255Sgblack@eecs.umich.edu if (shamt > 32) 2746255Sgblack@eecs.umich.edu return 0; 2756255Sgblack@eecs.umich.edu else 2766255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2776255Sgblack@eecs.umich.edu case ASR: 2786255Sgblack@eecs.umich.edu if (shamt > 32) 2796255Sgblack@eecs.umich.edu shamt = 32; 2806255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2816255Sgblack@eecs.umich.edu case ROR: 2826255Sgblack@eecs.umich.edu shamt = shamt & 0x1f; 2836255Sgblack@eecs.umich.edu if (shamt == 0) 2846255Sgblack@eecs.umich.edu shamt = 32; 2856255Sgblack@eecs.umich.edu return (base >> (shamt - 1)) & 1; 2866255Sgblack@eecs.umich.edu default: 2876712Snate@binkert.org ccprintf(std::cerr, "Unhandled shift type\n"); 2886255Sgblack@eecs.umich.edu exit(1); 2896255Sgblack@eecs.umich.edu break; 2906254Sgblack@eecs.umich.edu } 2916254Sgblack@eecs.umich.edu return 0; 2926254Sgblack@eecs.umich.edu} 2936254Sgblack@eecs.umich.edu 29412104Snathanael.premillieu@arm.comvoid 29512104Snathanael.premillieu@arm.comArmStaticInst::printIntReg(std::ostream &os, RegIndex reg_idx) const 29612104Snathanael.premillieu@arm.com{ 29712104Snathanael.premillieu@arm.com if (aarch64) { 29812104Snathanael.premillieu@arm.com if (reg_idx == INTREG_UREG0) 29912104Snathanael.premillieu@arm.com ccprintf(os, "ureg0"); 30012104Snathanael.premillieu@arm.com else if (reg_idx == INTREG_SPX) 30112104Snathanael.premillieu@arm.com ccprintf(os, "%s%s", (intWidth == 32) ? "w" : "", "sp"); 30212104Snathanael.premillieu@arm.com else if (reg_idx == INTREG_X31) 30312104Snathanael.premillieu@arm.com ccprintf(os, "%szr", (intWidth == 32) ? "w" : "x"); 30412104Snathanael.premillieu@arm.com else 30512104Snathanael.premillieu@arm.com ccprintf(os, "%s%d", (intWidth == 32) ? "w" : "x", reg_idx); 30612104Snathanael.premillieu@arm.com } else { 30712104Snathanael.premillieu@arm.com switch (reg_idx) { 30812104Snathanael.premillieu@arm.com case PCReg: 30912104Snathanael.premillieu@arm.com ccprintf(os, "pc"); 31012104Snathanael.premillieu@arm.com break; 31112104Snathanael.premillieu@arm.com case StackPointerReg: 31212104Snathanael.premillieu@arm.com ccprintf(os, "sp"); 31312104Snathanael.premillieu@arm.com break; 31412104Snathanael.premillieu@arm.com case FramePointerReg: 31512104Snathanael.premillieu@arm.com ccprintf(os, "fp"); 31612104Snathanael.premillieu@arm.com break; 31712104Snathanael.premillieu@arm.com case ReturnAddressReg: 31812104Snathanael.premillieu@arm.com ccprintf(os, "lr"); 31912104Snathanael.premillieu@arm.com break; 32012104Snathanael.premillieu@arm.com default: 32112104Snathanael.premillieu@arm.com ccprintf(os, "r%d", reg_idx); 32212104Snathanael.premillieu@arm.com break; 32312104Snathanael.premillieu@arm.com } 32412104Snathanael.premillieu@arm.com } 32512104Snathanael.premillieu@arm.com} 3266254Sgblack@eecs.umich.edu 3276254Sgblack@eecs.umich.eduvoid 32812104Snathanael.premillieu@arm.comArmStaticInst::printFloatReg(std::ostream &os, RegIndex reg_idx) const 3296253Sgblack@eecs.umich.edu{ 33012104Snathanael.premillieu@arm.com ccprintf(os, "f%d", reg_idx); 33112104Snathanael.premillieu@arm.com} 3329913Ssteve.reinhardt@amd.com 33312104Snathanael.premillieu@arm.comvoid 33412109SRekai.GonzalezAlberquilla@arm.comArmStaticInst::printVecReg(std::ostream &os, RegIndex reg_idx) const 33512109SRekai.GonzalezAlberquilla@arm.com{ 33612109SRekai.GonzalezAlberquilla@arm.com ccprintf(os, "v%d", reg_idx); 33712109SRekai.GonzalezAlberquilla@arm.com} 33812109SRekai.GonzalezAlberquilla@arm.com 33912109SRekai.GonzalezAlberquilla@arm.comvoid 34012104Snathanael.premillieu@arm.comArmStaticInst::printCCReg(std::ostream &os, RegIndex reg_idx) const 34112104Snathanael.premillieu@arm.com{ 34212104Snathanael.premillieu@arm.com ccprintf(os, "cc_%s", ArmISA::ccRegName[reg_idx]); 34312104Snathanael.premillieu@arm.com} 34412104Snathanael.premillieu@arm.com 34512104Snathanael.premillieu@arm.comvoid 34612104Snathanael.premillieu@arm.comArmStaticInst::printMiscReg(std::ostream &os, RegIndex reg_idx) const 34712104Snathanael.premillieu@arm.com{ 34812104Snathanael.premillieu@arm.com assert(reg_idx < NUM_MISCREGS); 34912104Snathanael.premillieu@arm.com ccprintf(os, "%s", ArmISA::miscRegName[reg_idx]); 3506253Sgblack@eecs.umich.edu} 3516253Sgblack@eecs.umich.edu 3526262Sgblack@eecs.umich.eduvoid 3537148Sgblack@eecs.umich.eduArmStaticInst::printMnemonic(std::ostream &os, 3546262Sgblack@eecs.umich.edu const std::string &suffix, 35510037SARM gem5 Developers bool withPred, 35610037SARM gem5 Developers bool withCond64, 35710037SARM gem5 Developers ConditionCode cond64) const 3586262Sgblack@eecs.umich.edu{ 3596262Sgblack@eecs.umich.edu os << " " << mnemonic; 36010037SARM gem5 Developers if (withPred && !aarch64) { 36110037SARM gem5 Developers printCondition(os, machInst.condCode); 3627122Sgblack@eecs.umich.edu os << suffix; 36310037SARM gem5 Developers } else if (withCond64) { 36410037SARM gem5 Developers os << "."; 36510037SARM gem5 Developers printCondition(os, cond64); 36610037SARM gem5 Developers os << suffix; 36710037SARM gem5 Developers } 36810037SARM gem5 Developers if (machInst.bigThumb) 36910037SARM gem5 Developers os << ".w"; 37010037SARM gem5 Developers os << " "; 37110037SARM gem5 Developers} 37210037SARM gem5 Developers 37310037SARM gem5 Developersvoid 37410037SARM gem5 DevelopersArmStaticInst::printTarget(std::ostream &os, Addr target, 37510037SARM gem5 Developers const SymbolTable *symtab) const 37610037SARM gem5 Developers{ 37710037SARM gem5 Developers Addr symbolAddr; 37810037SARM gem5 Developers std::string symbol; 37910037SARM gem5 Developers 38010037SARM gem5 Developers if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) { 38110037SARM gem5 Developers ccprintf(os, "<%s", symbol); 38210037SARM gem5 Developers if (symbolAddr != target) 38310037SARM gem5 Developers ccprintf(os, "+%d>", target - symbolAddr); 38410037SARM gem5 Developers else 38510037SARM gem5 Developers ccprintf(os, ">"); 38610037SARM gem5 Developers } else { 38710037SARM gem5 Developers ccprintf(os, "%#x", target); 38810037SARM gem5 Developers } 38910037SARM gem5 Developers} 39010037SARM gem5 Developers 39110037SARM gem5 Developersvoid 39210037SARM gem5 DevelopersArmStaticInst::printCondition(std::ostream &os, 39310037SARM gem5 Developers unsigned code, 39410037SARM gem5 Developers bool noImplicit) const 39510037SARM gem5 Developers{ 39610037SARM gem5 Developers switch (code) { 39710037SARM gem5 Developers case COND_EQ: 39810037SARM gem5 Developers os << "eq"; 39910037SARM gem5 Developers break; 40010037SARM gem5 Developers case COND_NE: 40110037SARM gem5 Developers os << "ne"; 40210037SARM gem5 Developers break; 40310037SARM gem5 Developers case COND_CS: 40410037SARM gem5 Developers os << "cs"; 40510037SARM gem5 Developers break; 40610037SARM gem5 Developers case COND_CC: 40710037SARM gem5 Developers os << "cc"; 40810037SARM gem5 Developers break; 40910037SARM gem5 Developers case COND_MI: 41010037SARM gem5 Developers os << "mi"; 41110037SARM gem5 Developers break; 41210037SARM gem5 Developers case COND_PL: 41310037SARM gem5 Developers os << "pl"; 41410037SARM gem5 Developers break; 41510037SARM gem5 Developers case COND_VS: 41610037SARM gem5 Developers os << "vs"; 41710037SARM gem5 Developers break; 41810037SARM gem5 Developers case COND_VC: 41910037SARM gem5 Developers os << "vc"; 42010037SARM gem5 Developers break; 42110037SARM gem5 Developers case COND_HI: 42210037SARM gem5 Developers os << "hi"; 42310037SARM gem5 Developers break; 42410037SARM gem5 Developers case COND_LS: 42510037SARM gem5 Developers os << "ls"; 42610037SARM gem5 Developers break; 42710037SARM gem5 Developers case COND_GE: 42810037SARM gem5 Developers os << "ge"; 42910037SARM gem5 Developers break; 43010037SARM gem5 Developers case COND_LT: 43110037SARM gem5 Developers os << "lt"; 43210037SARM gem5 Developers break; 43310037SARM gem5 Developers case COND_GT: 43410037SARM gem5 Developers os << "gt"; 43510037SARM gem5 Developers break; 43610037SARM gem5 Developers case COND_LE: 43710037SARM gem5 Developers os << "le"; 43810037SARM gem5 Developers break; 43910037SARM gem5 Developers case COND_AL: 44010037SARM gem5 Developers // This one is implicit. 44110037SARM gem5 Developers if (noImplicit) 44210037SARM gem5 Developers os << "al"; 44310037SARM gem5 Developers break; 44410037SARM gem5 Developers case COND_UC: 44510037SARM gem5 Developers // Unconditional. 44610037SARM gem5 Developers if (noImplicit) 44710037SARM gem5 Developers os << "uc"; 44810037SARM gem5 Developers break; 44910037SARM gem5 Developers default: 45010037SARM gem5 Developers panic("Unrecognized condition code %d.\n", code); 4516262Sgblack@eecs.umich.edu } 4526262Sgblack@eecs.umich.edu} 4536262Sgblack@eecs.umich.edu 4546263Sgblack@eecs.umich.eduvoid 4557148Sgblack@eecs.umich.eduArmStaticInst::printMemSymbol(std::ostream &os, 4566263Sgblack@eecs.umich.edu const SymbolTable *symtab, 4576263Sgblack@eecs.umich.edu const std::string &prefix, 4586263Sgblack@eecs.umich.edu const Addr addr, 4596263Sgblack@eecs.umich.edu const std::string &suffix) const 4606263Sgblack@eecs.umich.edu{ 4616263Sgblack@eecs.umich.edu Addr symbolAddr; 4626263Sgblack@eecs.umich.edu std::string symbol; 4636263Sgblack@eecs.umich.edu if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) { 4646263Sgblack@eecs.umich.edu ccprintf(os, "%s%s", prefix, symbol); 4656263Sgblack@eecs.umich.edu if (symbolAddr != addr) 4666263Sgblack@eecs.umich.edu ccprintf(os, "+%d", addr - symbolAddr); 4676263Sgblack@eecs.umich.edu ccprintf(os, suffix); 4686263Sgblack@eecs.umich.edu } 4696263Sgblack@eecs.umich.edu} 4706263Sgblack@eecs.umich.edu 4716264Sgblack@eecs.umich.eduvoid 4727148Sgblack@eecs.umich.eduArmStaticInst::printShiftOperand(std::ostream &os, 4737142Sgblack@eecs.umich.edu IntRegIndex rm, 4747142Sgblack@eecs.umich.edu bool immShift, 4757142Sgblack@eecs.umich.edu uint32_t shiftAmt, 4767142Sgblack@eecs.umich.edu IntRegIndex rs, 4777142Sgblack@eecs.umich.edu ArmShiftType type) const 4786264Sgblack@eecs.umich.edu{ 4797142Sgblack@eecs.umich.edu bool firstOp = false; 4806264Sgblack@eecs.umich.edu 4817142Sgblack@eecs.umich.edu if (rm != INTREG_ZERO) { 48212104Snathanael.premillieu@arm.com printIntReg(os, rm); 4837142Sgblack@eecs.umich.edu } 4847142Sgblack@eecs.umich.edu 4856306Sgblack@eecs.umich.edu bool done = false; 4866264Sgblack@eecs.umich.edu 4876306Sgblack@eecs.umich.edu if ((type == LSR || type == ASR) && immShift && shiftAmt == 0) 4886306Sgblack@eecs.umich.edu shiftAmt = 32; 4896264Sgblack@eecs.umich.edu 4906306Sgblack@eecs.umich.edu switch (type) { 4916306Sgblack@eecs.umich.edu case LSL: 4926306Sgblack@eecs.umich.edu if (immShift && shiftAmt == 0) { 4936306Sgblack@eecs.umich.edu done = true; 4946264Sgblack@eecs.umich.edu break; 4956306Sgblack@eecs.umich.edu } 4967142Sgblack@eecs.umich.edu if (!firstOp) 4977142Sgblack@eecs.umich.edu os << ", "; 4987142Sgblack@eecs.umich.edu os << "LSL"; 4996306Sgblack@eecs.umich.edu break; 5006306Sgblack@eecs.umich.edu case LSR: 5017142Sgblack@eecs.umich.edu if (!firstOp) 5027142Sgblack@eecs.umich.edu os << ", "; 5037142Sgblack@eecs.umich.edu os << "LSR"; 5046306Sgblack@eecs.umich.edu break; 5056306Sgblack@eecs.umich.edu case ASR: 5067142Sgblack@eecs.umich.edu if (!firstOp) 5077142Sgblack@eecs.umich.edu os << ", "; 5087142Sgblack@eecs.umich.edu os << "ASR"; 5096306Sgblack@eecs.umich.edu break; 5106306Sgblack@eecs.umich.edu case ROR: 5116306Sgblack@eecs.umich.edu if (immShift && shiftAmt == 0) { 5127142Sgblack@eecs.umich.edu if (!firstOp) 5137142Sgblack@eecs.umich.edu os << ", "; 5147142Sgblack@eecs.umich.edu os << "RRX"; 5156306Sgblack@eecs.umich.edu done = true; 5166264Sgblack@eecs.umich.edu break; 5176264Sgblack@eecs.umich.edu } 5187142Sgblack@eecs.umich.edu if (!firstOp) 5197142Sgblack@eecs.umich.edu os << ", "; 5207142Sgblack@eecs.umich.edu os << "ROR"; 5216306Sgblack@eecs.umich.edu break; 5226306Sgblack@eecs.umich.edu default: 5236306Sgblack@eecs.umich.edu panic("Tried to disassemble unrecognized shift type.\n"); 5246306Sgblack@eecs.umich.edu } 5256306Sgblack@eecs.umich.edu if (!done) { 5267142Sgblack@eecs.umich.edu if (!firstOp) 5277142Sgblack@eecs.umich.edu os << " "; 5286306Sgblack@eecs.umich.edu if (immShift) 5296306Sgblack@eecs.umich.edu os << "#" << shiftAmt; 5306306Sgblack@eecs.umich.edu else 53112104Snathanael.premillieu@arm.com printIntReg(os, rs); 5326264Sgblack@eecs.umich.edu } 5336264Sgblack@eecs.umich.edu} 5346264Sgblack@eecs.umich.edu 5356264Sgblack@eecs.umich.eduvoid 53610037SARM gem5 DevelopersArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os, 53710037SARM gem5 Developers IntRegIndex rm, ArmExtendType type, 53810037SARM gem5 Developers int64_t shiftAmt) const 53910037SARM gem5 Developers{ 54010037SARM gem5 Developers if (!firstOperand) 54110037SARM gem5 Developers ccprintf(os, ", "); 54212104Snathanael.premillieu@arm.com printIntReg(os, rm); 54310037SARM gem5 Developers if (type == UXTX && shiftAmt == 0) 54410037SARM gem5 Developers return; 54510037SARM gem5 Developers switch (type) { 54610037SARM gem5 Developers case UXTB: ccprintf(os, ", UXTB"); 54710037SARM gem5 Developers break; 54810037SARM gem5 Developers case UXTH: ccprintf(os, ", UXTH"); 54910037SARM gem5 Developers break; 55010037SARM gem5 Developers case UXTW: ccprintf(os, ", UXTW"); 55110037SARM gem5 Developers break; 55210037SARM gem5 Developers case UXTX: ccprintf(os, ", LSL"); 55310037SARM gem5 Developers break; 55410037SARM gem5 Developers case SXTB: ccprintf(os, ", SXTB"); 55510037SARM gem5 Developers break; 55610037SARM gem5 Developers case SXTH: ccprintf(os, ", SXTH"); 55710037SARM gem5 Developers break; 55810037SARM gem5 Developers case SXTW: ccprintf(os, ", SXTW"); 55910037SARM gem5 Developers break; 56010037SARM gem5 Developers case SXTX: ccprintf(os, ", SXTW"); 56110037SARM gem5 Developers break; 56210037SARM gem5 Developers } 56310037SARM gem5 Developers if (type == UXTX || shiftAmt) 56410037SARM gem5 Developers ccprintf(os, " #%d", shiftAmt); 56510037SARM gem5 Developers} 56610037SARM gem5 Developers 56710037SARM gem5 Developersvoid 5687148Sgblack@eecs.umich.eduArmStaticInst::printDataInst(std::ostream &os, bool withImm, 5697142Sgblack@eecs.umich.edu bool immShift, bool s, IntRegIndex rd, IntRegIndex rn, 5707142Sgblack@eecs.umich.edu IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt, 57111371Snathanael.premillieu@arm.com ArmShiftType type, uint64_t imm) const 5726264Sgblack@eecs.umich.edu{ 5737142Sgblack@eecs.umich.edu printMnemonic(os, s ? "s" : ""); 5746264Sgblack@eecs.umich.edu bool firstOp = true; 5756264Sgblack@eecs.umich.edu 5766264Sgblack@eecs.umich.edu // Destination 5777142Sgblack@eecs.umich.edu if (rd != INTREG_ZERO) { 5786264Sgblack@eecs.umich.edu firstOp = false; 57912104Snathanael.premillieu@arm.com printIntReg(os, rd); 5806264Sgblack@eecs.umich.edu } 5816264Sgblack@eecs.umich.edu 5826264Sgblack@eecs.umich.edu // Source 1. 5837142Sgblack@eecs.umich.edu if (rn != INTREG_ZERO) { 5846264Sgblack@eecs.umich.edu if (!firstOp) 5856264Sgblack@eecs.umich.edu os << ", "; 5866264Sgblack@eecs.umich.edu firstOp = false; 58712104Snathanael.premillieu@arm.com printIntReg(os, rn); 5886264Sgblack@eecs.umich.edu } 5896264Sgblack@eecs.umich.edu 5906264Sgblack@eecs.umich.edu if (!firstOp) 5916264Sgblack@eecs.umich.edu os << ", "; 5926306Sgblack@eecs.umich.edu if (withImm) { 59311371Snathanael.premillieu@arm.com ccprintf(os, "#%ld", imm); 5946306Sgblack@eecs.umich.edu } else { 5957142Sgblack@eecs.umich.edu printShiftOperand(os, rm, immShift, shiftAmt, rs, type); 5966306Sgblack@eecs.umich.edu } 5976264Sgblack@eecs.umich.edu} 5986264Sgblack@eecs.umich.edu 5996254Sgblack@eecs.umich.edustd::string 6007148Sgblack@eecs.umich.eduArmStaticInst::generateDisassembly(Addr pc, 6016254Sgblack@eecs.umich.edu const SymbolTable *symtab) const 6026253Sgblack@eecs.umich.edu{ 6036253Sgblack@eecs.umich.edu std::stringstream ss; 6046262Sgblack@eecs.umich.edu printMnemonic(ss); 6056253Sgblack@eecs.umich.edu return ss.str(); 6066253Sgblack@eecs.umich.edu} 60711513Sandreas.sandberg@arm.com 60811513Sandreas.sandberg@arm.com 60911513Sandreas.sandberg@arm.comFault 61011513Sandreas.sandberg@arm.comArmStaticInst::advSIMDFPAccessTrap64(ExceptionLevel el) const 61111513Sandreas.sandberg@arm.com{ 61211513Sandreas.sandberg@arm.com switch (el) { 61311513Sandreas.sandberg@arm.com case EL1: 61411513Sandreas.sandberg@arm.com return std::make_shared<SupervisorTrap>(machInst, 0x1E00000, 61511513Sandreas.sandberg@arm.com EC_TRAPPED_SIMD_FP); 61611513Sandreas.sandberg@arm.com case EL2: 61711513Sandreas.sandberg@arm.com return std::make_shared<HypervisorTrap>(machInst, 0x1E00000, 61811513Sandreas.sandberg@arm.com EC_TRAPPED_SIMD_FP); 61911513Sandreas.sandberg@arm.com case EL3: 62011513Sandreas.sandberg@arm.com return std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000, 62111513Sandreas.sandberg@arm.com EC_TRAPPED_SIMD_FP); 62211513Sandreas.sandberg@arm.com 62311513Sandreas.sandberg@arm.com default: 62411513Sandreas.sandberg@arm.com panic("Illegal EL in advSIMDFPAccessTrap64\n"); 62511513Sandreas.sandberg@arm.com } 6266253Sgblack@eecs.umich.edu} 62711513Sandreas.sandberg@arm.com 62811513Sandreas.sandberg@arm.com 62911513Sandreas.sandberg@arm.comFault 63011513Sandreas.sandberg@arm.comArmStaticInst::checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const 63111513Sandreas.sandberg@arm.com{ 63211513Sandreas.sandberg@arm.com const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el; 63311513Sandreas.sandberg@arm.com 63411513Sandreas.sandberg@arm.com if (ArmSystem::haveVirtualization(tc) && el <= EL2) { 63511513Sandreas.sandberg@arm.com HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL2); 63611513Sandreas.sandberg@arm.com if (cptrEnCheck.tfp) 63711513Sandreas.sandberg@arm.com return advSIMDFPAccessTrap64(EL2); 63811513Sandreas.sandberg@arm.com } 63911513Sandreas.sandberg@arm.com 64011513Sandreas.sandberg@arm.com if (ArmSystem::haveSecurity(tc)) { 64111513Sandreas.sandberg@arm.com HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3); 64211513Sandreas.sandberg@arm.com if (cptrEnCheck.tfp) 64311513Sandreas.sandberg@arm.com return advSIMDFPAccessTrap64(EL3); 64411513Sandreas.sandberg@arm.com } 64511513Sandreas.sandberg@arm.com 64611513Sandreas.sandberg@arm.com return NoFault; 64711513Sandreas.sandberg@arm.com} 64811513Sandreas.sandberg@arm.com 64911513Sandreas.sandberg@arm.comFault 65011513Sandreas.sandberg@arm.comArmStaticInst::checkFPAdvSIMDEnabled64(ThreadContext *tc, 65111513Sandreas.sandberg@arm.com CPSR cpsr, CPACR cpacr) const 65211513Sandreas.sandberg@arm.com{ 65311513Sandreas.sandberg@arm.com const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el; 65411513Sandreas.sandberg@arm.com if ((el == EL0 && cpacr.fpen != 0x3) || 65511513Sandreas.sandberg@arm.com (el == EL1 && !(cpacr.fpen & 0x1))) 65611513Sandreas.sandberg@arm.com return advSIMDFPAccessTrap64(EL1); 65711513Sandreas.sandberg@arm.com 65811513Sandreas.sandberg@arm.com return checkFPAdvSIMDTrap64(tc, cpsr); 65911513Sandreas.sandberg@arm.com} 66011513Sandreas.sandberg@arm.com 66111513Sandreas.sandberg@arm.comFault 66211513Sandreas.sandberg@arm.comArmStaticInst::checkAdvSIMDOrFPEnabled32(ThreadContext *tc, 66311513Sandreas.sandberg@arm.com CPSR cpsr, CPACR cpacr, 66411513Sandreas.sandberg@arm.com NSACR nsacr, FPEXC fpexc, 66511513Sandreas.sandberg@arm.com bool fpexc_check, bool advsimd) const 66611513Sandreas.sandberg@arm.com{ 66711513Sandreas.sandberg@arm.com const bool have_virtualization = ArmSystem::haveVirtualization(tc); 66811513Sandreas.sandberg@arm.com const bool have_security = ArmSystem::haveSecurity(tc); 66911513Sandreas.sandberg@arm.com const bool is_secure = inSecureState(tc); 67011513Sandreas.sandberg@arm.com const ExceptionLevel cur_el = opModeToEL(currOpMode(tc)); 67111513Sandreas.sandberg@arm.com 67211513Sandreas.sandberg@arm.com if (cur_el == EL0 && ELIs64(tc, EL1)) 67311513Sandreas.sandberg@arm.com return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr); 67411513Sandreas.sandberg@arm.com 67511513Sandreas.sandberg@arm.com uint8_t cpacr_cp10 = cpacr.cp10; 67611513Sandreas.sandberg@arm.com bool cpacr_asedis = cpacr.asedis; 67711513Sandreas.sandberg@arm.com 67811513Sandreas.sandberg@arm.com if (have_security && !ELIs64(tc, EL3) && !is_secure) { 67911513Sandreas.sandberg@arm.com if (nsacr.nsasedis) 68011513Sandreas.sandberg@arm.com cpacr_asedis = true; 68111513Sandreas.sandberg@arm.com if (nsacr.cp10 == 0) 68211513Sandreas.sandberg@arm.com cpacr_cp10 = 0; 68311513Sandreas.sandberg@arm.com } 68411513Sandreas.sandberg@arm.com 68511513Sandreas.sandberg@arm.com if (cur_el != EL2) { 68611513Sandreas.sandberg@arm.com if (advsimd && cpacr_asedis) 68711513Sandreas.sandberg@arm.com return disabledFault(); 68811513Sandreas.sandberg@arm.com 68911513Sandreas.sandberg@arm.com if ((cur_el == EL0 && cpacr_cp10 != 0x3) || 69011513Sandreas.sandberg@arm.com (cur_el != EL0 && !(cpacr_cp10 & 0x1))) 69111513Sandreas.sandberg@arm.com return disabledFault(); 69211513Sandreas.sandberg@arm.com } 69311513Sandreas.sandberg@arm.com 69411513Sandreas.sandberg@arm.com if (fpexc_check && !fpexc.en) 69511513Sandreas.sandberg@arm.com return disabledFault(); 69611513Sandreas.sandberg@arm.com 69711513Sandreas.sandberg@arm.com // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap -- 69811513Sandreas.sandberg@arm.com 69911513Sandreas.sandberg@arm.com if (have_virtualization && !is_secure && ELIs64(tc, EL2)) 70011513Sandreas.sandberg@arm.com return checkFPAdvSIMDTrap64(tc, cpsr); 70111513Sandreas.sandberg@arm.com 70211513Sandreas.sandberg@arm.com if (have_virtualization && !is_secure) { 70311513Sandreas.sandberg@arm.com HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR); 70411513Sandreas.sandberg@arm.com bool hcptr_cp10 = hcptr.tcp10; 70511513Sandreas.sandberg@arm.com bool hcptr_tase = hcptr.tase; 70611513Sandreas.sandberg@arm.com 70711513Sandreas.sandberg@arm.com if (have_security && !ELIs64(tc, EL3) && !is_secure) { 70811513Sandreas.sandberg@arm.com if (nsacr.nsasedis) 70911513Sandreas.sandberg@arm.com hcptr_tase = true; 71011513Sandreas.sandberg@arm.com if (nsacr.cp10) 71111513Sandreas.sandberg@arm.com hcptr_cp10 = true; 71211513Sandreas.sandberg@arm.com } 71311513Sandreas.sandberg@arm.com 71411513Sandreas.sandberg@arm.com if ((advsimd && hcptr_tase) || hcptr_cp10) { 71511513Sandreas.sandberg@arm.com const uint32_t iss = advsimd ? (1 << 5) : 0xA; 71611513Sandreas.sandberg@arm.com if (cur_el == EL2) { 71711513Sandreas.sandberg@arm.com return std::make_shared<UndefinedInstruction>( 71811513Sandreas.sandberg@arm.com machInst, iss, 71911513Sandreas.sandberg@arm.com EC_TRAPPED_HCPTR, mnemonic); 72011513Sandreas.sandberg@arm.com } else { 72111513Sandreas.sandberg@arm.com return std::make_shared<HypervisorTrap>( 72211513Sandreas.sandberg@arm.com machInst, iss, 72311513Sandreas.sandberg@arm.com EC_TRAPPED_HCPTR); 72411513Sandreas.sandberg@arm.com } 72511513Sandreas.sandberg@arm.com 72611513Sandreas.sandberg@arm.com } 72711513Sandreas.sandberg@arm.com } 72811513Sandreas.sandberg@arm.com 72911513Sandreas.sandberg@arm.com if (have_security && ELIs64(tc, EL3)) { 73011513Sandreas.sandberg@arm.com HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3); 73111513Sandreas.sandberg@arm.com if (cptrEnCheck.tfp) 73211513Sandreas.sandberg@arm.com return advSIMDFPAccessTrap64(EL3); 73311513Sandreas.sandberg@arm.com } 73411513Sandreas.sandberg@arm.com 73511513Sandreas.sandberg@arm.com return NoFault; 73611513Sandreas.sandberg@arm.com} 73711513Sandreas.sandberg@arm.com 73812403Sgiacomo.travaglini@arm.cominline bool 73912403Sgiacomo.travaglini@arm.comArmStaticInst::isWFxTrapping(ThreadContext *tc, 74012403Sgiacomo.travaglini@arm.com ExceptionLevel tgtEl, 74112403Sgiacomo.travaglini@arm.com bool isWfe) const 74212403Sgiacomo.travaglini@arm.com{ 74312403Sgiacomo.travaglini@arm.com bool trap = false; 74412403Sgiacomo.travaglini@arm.com SCTLR sctlr = ((SCTLR)tc->readMiscReg(MISCREG_SCTLR_EL1)); 74512403Sgiacomo.travaglini@arm.com HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2)); 74612403Sgiacomo.travaglini@arm.com SCR scr = ((SCR)tc->readMiscReg(MISCREG_SCR_EL3)); 74712403Sgiacomo.travaglini@arm.com 74812403Sgiacomo.travaglini@arm.com switch (tgtEl) { 74912403Sgiacomo.travaglini@arm.com case EL1: 75012403Sgiacomo.travaglini@arm.com trap = isWfe? !sctlr.ntwe : !sctlr.ntwi; 75112403Sgiacomo.travaglini@arm.com break; 75212403Sgiacomo.travaglini@arm.com case EL2: 75312403Sgiacomo.travaglini@arm.com trap = isWfe? hcr.twe : hcr.twi; 75412403Sgiacomo.travaglini@arm.com break; 75512403Sgiacomo.travaglini@arm.com case EL3: 75612403Sgiacomo.travaglini@arm.com trap = isWfe? scr.twe : scr.twi; 75712403Sgiacomo.travaglini@arm.com break; 75812403Sgiacomo.travaglini@arm.com default: 75912403Sgiacomo.travaglini@arm.com break; 76012403Sgiacomo.travaglini@arm.com } 76112403Sgiacomo.travaglini@arm.com 76212403Sgiacomo.travaglini@arm.com return trap; 76312403Sgiacomo.travaglini@arm.com} 76412403Sgiacomo.travaglini@arm.com 76512403Sgiacomo.travaglini@arm.comFault 76612403Sgiacomo.travaglini@arm.comArmStaticInst::checkForWFxTrap32(ThreadContext *tc, 76712403Sgiacomo.travaglini@arm.com ExceptionLevel targetEL, 76812403Sgiacomo.travaglini@arm.com bool isWfe) const 76912403Sgiacomo.travaglini@arm.com{ 77012403Sgiacomo.travaglini@arm.com // Check if target exception level is implemented. 77112403Sgiacomo.travaglini@arm.com assert(ArmSystem::haveEL(tc, targetEL)); 77212403Sgiacomo.travaglini@arm.com 77312403Sgiacomo.travaglini@arm.com // Check for routing to AArch64: this happens if the 77412403Sgiacomo.travaglini@arm.com // target exception level (where the trap will be handled) 77512403Sgiacomo.travaglini@arm.com // is using aarch64 77612403Sgiacomo.travaglini@arm.com if (ELIs64(tc, targetEL)) { 77712403Sgiacomo.travaglini@arm.com return checkForWFxTrap64(tc, targetEL, isWfe); 77812403Sgiacomo.travaglini@arm.com } 77912403Sgiacomo.travaglini@arm.com 78012403Sgiacomo.travaglini@arm.com // Check if processor needs to trap at selected exception level 78112403Sgiacomo.travaglini@arm.com bool trap = isWFxTrapping(tc, targetEL, isWfe); 78212403Sgiacomo.travaglini@arm.com 78312403Sgiacomo.travaglini@arm.com if (trap) { 78412403Sgiacomo.travaglini@arm.com uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */ 78512403Sgiacomo.travaglini@arm.com 0x1E00000; /* WFI Instruction syndrome */ 78612403Sgiacomo.travaglini@arm.com switch (targetEL) { 78712403Sgiacomo.travaglini@arm.com case EL1: 78812403Sgiacomo.travaglini@arm.com return std::make_shared<UndefinedInstruction>( 78912403Sgiacomo.travaglini@arm.com machInst, iss, 79012403Sgiacomo.travaglini@arm.com EC_TRAPPED_WFI_WFE, mnemonic); 79112403Sgiacomo.travaglini@arm.com case EL2: 79212403Sgiacomo.travaglini@arm.com return std::make_shared<HypervisorTrap>(machInst, iss, 79312403Sgiacomo.travaglini@arm.com EC_TRAPPED_WFI_WFE); 79412403Sgiacomo.travaglini@arm.com case EL3: 79512403Sgiacomo.travaglini@arm.com return std::make_shared<SecureMonitorTrap>(machInst, iss, 79612403Sgiacomo.travaglini@arm.com EC_TRAPPED_WFI_WFE); 79712403Sgiacomo.travaglini@arm.com default: 79812403Sgiacomo.travaglini@arm.com panic("Unrecognized Exception Level: %d\n", targetEL); 79912403Sgiacomo.travaglini@arm.com } 80012403Sgiacomo.travaglini@arm.com } 80112403Sgiacomo.travaglini@arm.com 80212403Sgiacomo.travaglini@arm.com return NoFault; 80312403Sgiacomo.travaglini@arm.com} 80412403Sgiacomo.travaglini@arm.com 80512403Sgiacomo.travaglini@arm.comFault 80612403Sgiacomo.travaglini@arm.comArmStaticInst::checkForWFxTrap64(ThreadContext *tc, 80712403Sgiacomo.travaglini@arm.com ExceptionLevel targetEL, 80812403Sgiacomo.travaglini@arm.com bool isWfe) const 80912403Sgiacomo.travaglini@arm.com{ 81012403Sgiacomo.travaglini@arm.com // Check if target exception level is implemented. 81112403Sgiacomo.travaglini@arm.com assert(ArmSystem::haveEL(tc, targetEL)); 81212403Sgiacomo.travaglini@arm.com 81312403Sgiacomo.travaglini@arm.com // Check if processor needs to trap at selected exception level 81412403Sgiacomo.travaglini@arm.com bool trap = isWFxTrapping(tc, targetEL, isWfe); 81512403Sgiacomo.travaglini@arm.com 81612403Sgiacomo.travaglini@arm.com if (trap) { 81712403Sgiacomo.travaglini@arm.com uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */ 81812403Sgiacomo.travaglini@arm.com 0x1E00000; /* WFI Instruction syndrome */ 81912403Sgiacomo.travaglini@arm.com switch (targetEL) { 82012403Sgiacomo.travaglini@arm.com case EL1: 82112403Sgiacomo.travaglini@arm.com return std::make_shared<SupervisorTrap>(machInst, iss, 82212403Sgiacomo.travaglini@arm.com EC_TRAPPED_WFI_WFE); 82312403Sgiacomo.travaglini@arm.com case EL2: 82412403Sgiacomo.travaglini@arm.com return std::make_shared<HypervisorTrap>(machInst, iss, 82512403Sgiacomo.travaglini@arm.com EC_TRAPPED_WFI_WFE); 82612403Sgiacomo.travaglini@arm.com case EL3: 82712403Sgiacomo.travaglini@arm.com return std::make_shared<SecureMonitorTrap>(machInst, iss, 82812403Sgiacomo.travaglini@arm.com EC_TRAPPED_WFI_WFE); 82912403Sgiacomo.travaglini@arm.com default: 83012403Sgiacomo.travaglini@arm.com panic("Unrecognized Exception Level: %d\n", targetEL); 83112403Sgiacomo.travaglini@arm.com } 83212403Sgiacomo.travaglini@arm.com } 83312403Sgiacomo.travaglini@arm.com 83412403Sgiacomo.travaglini@arm.com return NoFault; 83512403Sgiacomo.travaglini@arm.com} 83612403Sgiacomo.travaglini@arm.com 83712403Sgiacomo.travaglini@arm.comFault 83812403Sgiacomo.travaglini@arm.comArmStaticInst::trapWFx(ThreadContext *tc, 83912403Sgiacomo.travaglini@arm.com CPSR cpsr, SCR scr, 84012403Sgiacomo.travaglini@arm.com bool isWfe) const 84112403Sgiacomo.travaglini@arm.com{ 84212403Sgiacomo.travaglini@arm.com Fault fault = NoFault; 84312403Sgiacomo.travaglini@arm.com if (cpsr.el == EL0) { 84412403Sgiacomo.travaglini@arm.com fault = checkForWFxTrap32(tc, EL1, isWfe); 84512403Sgiacomo.travaglini@arm.com } 84612403Sgiacomo.travaglini@arm.com 84712403Sgiacomo.travaglini@arm.com if ((fault == NoFault) && 84812403Sgiacomo.travaglini@arm.com ArmSystem::haveEL(tc, EL2) && !inSecureState(scr, cpsr) && 84912403Sgiacomo.travaglini@arm.com ((cpsr.el == EL0) || (cpsr.el == EL1))) { 85012403Sgiacomo.travaglini@arm.com 85112403Sgiacomo.travaglini@arm.com fault = checkForWFxTrap32(tc, EL2, isWfe); 85212403Sgiacomo.travaglini@arm.com } 85312403Sgiacomo.travaglini@arm.com 85412403Sgiacomo.travaglini@arm.com if ((fault == NoFault) && 85512403Sgiacomo.travaglini@arm.com ArmSystem::haveEL(tc, EL3) && cpsr.el != EL3) { 85612403Sgiacomo.travaglini@arm.com fault = checkForWFxTrap32(tc, EL3, isWfe); 85712403Sgiacomo.travaglini@arm.com } 85812403Sgiacomo.travaglini@arm.com 85912403Sgiacomo.travaglini@arm.com return fault; 86012403Sgiacomo.travaglini@arm.com} 86111513Sandreas.sandberg@arm.com 86211514Sandreas.sandberg@arm.comstatic uint8_t 86311514Sandreas.sandberg@arm.comgetRestoredITBits(ThreadContext *tc, CPSR spsr) 86411514Sandreas.sandberg@arm.com{ 86511514Sandreas.sandberg@arm.com // See: shared/functions/system/RestoredITBits in the ARM ARM 86611514Sandreas.sandberg@arm.com 86711514Sandreas.sandberg@arm.com const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode); 86811514Sandreas.sandberg@arm.com const uint8_t it = itState(spsr); 86911514Sandreas.sandberg@arm.com 87011514Sandreas.sandberg@arm.com if (!spsr.t || spsr.il) 87111514Sandreas.sandberg@arm.com return 0; 87211514Sandreas.sandberg@arm.com 87311514Sandreas.sandberg@arm.com // The IT bits are forced to zero when they are set to a reserved 87411514Sandreas.sandberg@arm.com // value. 87511514Sandreas.sandberg@arm.com if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0) 87611514Sandreas.sandberg@arm.com return 0; 87711514Sandreas.sandberg@arm.com 87811514Sandreas.sandberg@arm.com const bool itd = el == EL2 ? 87911514Sandreas.sandberg@arm.com ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd : 88011514Sandreas.sandberg@arm.com ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd; 88111514Sandreas.sandberg@arm.com 88211514Sandreas.sandberg@arm.com // The IT bits are forced to zero when returning to A32 state, or 88311514Sandreas.sandberg@arm.com // when returning to an EL with the ITD bit set to 1, and the IT 88411514Sandreas.sandberg@arm.com // bits are describing a multi-instruction block. 88511514Sandreas.sandberg@arm.com if (itd && bits(it, 2, 0) != 0) 88611514Sandreas.sandberg@arm.com return 0; 88711514Sandreas.sandberg@arm.com 88811514Sandreas.sandberg@arm.com return it; 88911513Sandreas.sandberg@arm.com} 89011514Sandreas.sandberg@arm.com 89111514Sandreas.sandberg@arm.comstatic bool 89211514Sandreas.sandberg@arm.comillegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr) 89311514Sandreas.sandberg@arm.com{ 89411514Sandreas.sandberg@arm.com const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode; 89511514Sandreas.sandberg@arm.com if (badMode(mode)) 89611514Sandreas.sandberg@arm.com return true; 89711514Sandreas.sandberg@arm.com 89811514Sandreas.sandberg@arm.com const OperatingMode cur_mode = (OperatingMode) (uint8_t)cpsr.mode; 89911514Sandreas.sandberg@arm.com const ExceptionLevel target_el = opModeToEL(mode); 90011514Sandreas.sandberg@arm.com if (target_el > opModeToEL(cur_mode)) 90111514Sandreas.sandberg@arm.com return true; 90211514Sandreas.sandberg@arm.com 90311514Sandreas.sandberg@arm.com if (target_el == EL3 && !ArmSystem::haveSecurity(tc)) 90411514Sandreas.sandberg@arm.com return true; 90511514Sandreas.sandberg@arm.com 90611514Sandreas.sandberg@arm.com if (target_el == EL2 && !ArmSystem::haveVirtualization(tc)) 90711514Sandreas.sandberg@arm.com return true; 90811514Sandreas.sandberg@arm.com 90911514Sandreas.sandberg@arm.com if (!spsr.width) { 91011514Sandreas.sandberg@arm.com // aarch64 91111514Sandreas.sandberg@arm.com if (!ArmSystem::highestELIs64(tc)) 91211514Sandreas.sandberg@arm.com return true; 91311514Sandreas.sandberg@arm.com 91411514Sandreas.sandberg@arm.com if (spsr & 0x2) 91511514Sandreas.sandberg@arm.com return true; 91611514Sandreas.sandberg@arm.com if (target_el == EL0 && spsr.sp) 91711514Sandreas.sandberg@arm.com return true; 91811514Sandreas.sandberg@arm.com if (target_el == EL2 && !((SCR)tc->readMiscReg(MISCREG_SCR_EL3)).ns) 91911514Sandreas.sandberg@arm.com return false; 92011514Sandreas.sandberg@arm.com } else { 92111514Sandreas.sandberg@arm.com return badMode32(mode); 92211514Sandreas.sandberg@arm.com } 92311514Sandreas.sandberg@arm.com 92411514Sandreas.sandberg@arm.com return false; 92511514Sandreas.sandberg@arm.com} 92611514Sandreas.sandberg@arm.com 92711514Sandreas.sandberg@arm.comCPSR 92811514Sandreas.sandberg@arm.comArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const 92911514Sandreas.sandberg@arm.com{ 93011514Sandreas.sandberg@arm.com CPSR new_cpsr = 0; 93111514Sandreas.sandberg@arm.com 93211514Sandreas.sandberg@arm.com // gem5 doesn't implement single-stepping, so force the SS bit to 93311514Sandreas.sandberg@arm.com // 0. 93411514Sandreas.sandberg@arm.com new_cpsr.ss = 0; 93511514Sandreas.sandberg@arm.com 93611514Sandreas.sandberg@arm.com if (illegalExceptionReturn(tc, cpsr, spsr)) { 93711514Sandreas.sandberg@arm.com new_cpsr.il = 1; 93811514Sandreas.sandberg@arm.com } else { 93911514Sandreas.sandberg@arm.com new_cpsr.il = spsr.il; 94011514Sandreas.sandberg@arm.com if (spsr.width && badMode32((OperatingMode)(uint8_t)spsr.mode)) { 94111514Sandreas.sandberg@arm.com new_cpsr.il = 1; 94211514Sandreas.sandberg@arm.com } else if (spsr.width) { 94311514Sandreas.sandberg@arm.com new_cpsr.mode = spsr.mode; 94411514Sandreas.sandberg@arm.com } else { 94511514Sandreas.sandberg@arm.com new_cpsr.el = spsr.el; 94611514Sandreas.sandberg@arm.com new_cpsr.sp = spsr.sp; 94711514Sandreas.sandberg@arm.com } 94811514Sandreas.sandberg@arm.com } 94911514Sandreas.sandberg@arm.com 95011514Sandreas.sandberg@arm.com new_cpsr.nz = spsr.nz; 95111514Sandreas.sandberg@arm.com new_cpsr.c = spsr.c; 95211514Sandreas.sandberg@arm.com new_cpsr.v = spsr.v; 95311514Sandreas.sandberg@arm.com if (new_cpsr.width) { 95411514Sandreas.sandberg@arm.com // aarch32 95511514Sandreas.sandberg@arm.com const ITSTATE it = getRestoredITBits(tc, spsr); 95611514Sandreas.sandberg@arm.com new_cpsr.q = spsr.q; 95711514Sandreas.sandberg@arm.com new_cpsr.ge = spsr.ge; 95811514Sandreas.sandberg@arm.com new_cpsr.e = spsr.e; 95911514Sandreas.sandberg@arm.com new_cpsr.aif = spsr.aif; 96011514Sandreas.sandberg@arm.com new_cpsr.t = spsr.t; 96111514Sandreas.sandberg@arm.com new_cpsr.it2 = it.top6; 96211514Sandreas.sandberg@arm.com new_cpsr.it1 = it.bottom2; 96311514Sandreas.sandberg@arm.com } else { 96411514Sandreas.sandberg@arm.com // aarch64 96511514Sandreas.sandberg@arm.com new_cpsr.daif = spsr.daif; 96611514Sandreas.sandberg@arm.com } 96711514Sandreas.sandberg@arm.com 96811514Sandreas.sandberg@arm.com return new_cpsr; 96911514Sandreas.sandberg@arm.com} 97011514Sandreas.sandberg@arm.com 97111514Sandreas.sandberg@arm.com 97211514Sandreas.sandberg@arm.com 97311514Sandreas.sandberg@arm.com} 974