static_inst.cc revision 12104:edd63f9c6184
11689SN/A/* 29444SAndreas.Sandberg@ARM.com * Copyright (c) 2010-2014, 2016 ARM Limited 38707Sandreas.hansson@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 48707Sandreas.hansson@arm.com * All rights reserved 58707Sandreas.hansson@arm.com * 68707Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 78707Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 88707Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 98707Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 108707Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 118707Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 128707Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 138707Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 141689SN/A * 157897Shestness@cs.utexas.edu * Copyright (c) 2007-2008 The Florida State University 161689SN/A * All rights reserved. 171689SN/A * 181689SN/A * Redistribution and use in source and binary forms, with or without 191689SN/A * modification, are permitted provided that the following conditions are 201689SN/A * met: redistributions of source code must retain the above copyright 211689SN/A * notice, this list of conditions and the following disclaimer; 221689SN/A * redistributions in binary form must reproduce the above copyright 231689SN/A * notice, this list of conditions and the following disclaimer in the 241689SN/A * documentation and/or other materials provided with the distribution; 251689SN/A * neither the name of the copyright holders nor the names of its 261689SN/A * contributors may be used to endorse or promote products derived from 271689SN/A * this software without specific prior written permission. 281689SN/A * 291689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 301689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 311689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 321689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 331689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 341689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 351689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 361689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 371689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 381689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 391689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 412665Ssaidi@eecs.umich.edu * Authors: Stephen Hines 422756Sksewell@umich.edu */ 437897Shestness@cs.utexas.edu 441689SN/A#include "arch/arm/insts/static_inst.hh" 451689SN/A 462325SN/A#include "arch/arm/faults.hh" 472325SN/A#include "base/condcodes.hh" 481060SN/A#include "base/cprintf.hh" 491060SN/A#include "base/loader/symtab.hh" 501060SN/A#include "cpu/reg_class.hh" 512292SN/A 522292SN/Anamespace ArmISA 531681SN/A{ 541060SN/A// Shift Rm by an immediate value 552980Sgblack@eecs.umich.eduint32_t 561060SN/AArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt, 576658Snate@binkert.org uint32_t type, uint32_t cfval) const 581717SN/A{ 591717SN/A assert(shamt < 32); 602292SN/A ArmShiftType shiftType; 612292SN/A shiftType = (ArmShiftType)type; 628229Snate@binkert.org 638229Snate@binkert.org switch (shiftType) 648229Snate@binkert.org { 658229Snate@binkert.org case LSL: 662817Sksewell@umich.edu return base << shamt; 678229Snate@binkert.org case LSR: 681060SN/A if (shamt == 0) 691060SN/A return 0; 702316SN/A else 712316SN/A return base >> shamt; 722680Sktlim@umich.edu case ASR: 732817Sksewell@umich.edu if (shamt == 0) 742817Sksewell@umich.edu return (base >> 31) | -((base & (1 << 31)) >> 31); 752843Sktlim@umich.edu else 762843Sktlim@umich.edu return (base >> shamt) | -((base & (1 << 31)) >> shamt); 772669Sktlim@umich.edu case ROR: 781060SN/A if (shamt == 0) 791060SN/A return (cfval << 31) | (base >> 1); // RRX 808737Skoansin.tan@gmail.com else 815529Snate@binkert.org return (base << (32 - shamt)) | (base >> shamt); 822733Sktlim@umich.edu default: 831060SN/A ccprintf(std::cerr, "Unhandled shift type\n"); 841060SN/A exit(1); 851060SN/A break; 865529Snate@binkert.org } 872292SN/A return 0; 882292SN/A} 891060SN/A 901060SN/Aint64_t 912348SN/AArmStaticInst::shiftReg64(uint64_t base, uint64_t shiftAmt, 922348SN/A ArmShiftType type, uint8_t width) const 932348SN/A{ 942348SN/A shiftAmt = shiftAmt % width; 952348SN/A ArmShiftType shiftType; 961060SN/A shiftType = (ArmShiftType)type; 972733Sktlim@umich.edu 981060SN/A switch (shiftType) 991060SN/A { 1002325SN/A case LSL: 1011060SN/A return base << shiftAmt; 1021061SN/A case LSR: 1034329Sktlim@umich.edu if (shiftAmt == 0) 1041060SN/A return base; 1055595Sgblack@eecs.umich.edu else 1062292SN/A return (base & mask(width)) >> shiftAmt; 1072292SN/A case ASR: 1082292SN/A if (shiftAmt == 0) { 1092292SN/A return base; 1102817Sksewell@umich.edu } else { 1112829Sksewell@umich.edu int sign_bit = bits(base, intWidth - 1); 1121060SN/A base >>= shiftAmt; 1131060SN/A base = sign_bit ? (base | ~mask(intWidth - shiftAmt)) : base; 1141060SN/A return base & mask(intWidth); 1151060SN/A } 1161060SN/A case ROR: 1172307SN/A if (shiftAmt == 0) 1182307SN/A return base; 1191060SN/A else 1201060SN/A return (base << (width - shiftAmt)) | (base >> shiftAmt); 1216022Sgblack@eecs.umich.edu default: 1226022Sgblack@eecs.umich.edu ccprintf(std::cerr, "Unhandled shift type\n"); 1233781Sgblack@eecs.umich.edu exit(1); 1242292SN/A break; 1251060SN/A } 1261060SN/A return 0; 1271060SN/A} 1288707Sandreas.hansson@arm.com 1298707Sandreas.hansson@arm.comint64_t 1308707Sandreas.hansson@arm.comArmStaticInst::extendReg64(uint64_t base, ArmExtendType type, 1318707Sandreas.hansson@arm.com uint64_t shiftAmt, uint8_t width) const 1328707Sandreas.hansson@arm.com{ 1338707Sandreas.hansson@arm.com bool sign_extend = false; 1348707Sandreas.hansson@arm.com int len = 0; 1358707Sandreas.hansson@arm.com switch (type) { 1368707Sandreas.hansson@arm.com case UXTB: 1378707Sandreas.hansson@arm.com len = 8; 1388707Sandreas.hansson@arm.com break; 1398707Sandreas.hansson@arm.com case UXTH: 1408707Sandreas.hansson@arm.com len = 16; 1419095Sandreas.hansson@arm.com break; 1428707Sandreas.hansson@arm.com case UXTW: 1438707Sandreas.hansson@arm.com len = 32; 1448707Sandreas.hansson@arm.com break; 1458707Sandreas.hansson@arm.com case UXTX: 1468707Sandreas.hansson@arm.com len = 64; 1478707Sandreas.hansson@arm.com break; 1488975Sandreas.hansson@arm.com case SXTB: 1498975Sandreas.hansson@arm.com len = 8; 1508707Sandreas.hansson@arm.com sign_extend = true; 1518707Sandreas.hansson@arm.com break; 1528707Sandreas.hansson@arm.com case SXTH: 1538707Sandreas.hansson@arm.com len = 16; 1548707Sandreas.hansson@arm.com sign_extend = true; 1558707Sandreas.hansson@arm.com break; 1568707Sandreas.hansson@arm.com case SXTW: 1578707Sandreas.hansson@arm.com len = 32; 1588707Sandreas.hansson@arm.com sign_extend = true; 1598707Sandreas.hansson@arm.com break; 1608707Sandreas.hansson@arm.com case SXTX: 1618707Sandreas.hansson@arm.com len = 64; 1628707Sandreas.hansson@arm.com sign_extend = true; 1638707Sandreas.hansson@arm.com break; 1648707Sandreas.hansson@arm.com } 1658707Sandreas.hansson@arm.com len = len <= width - shiftAmt ? len : width - shiftAmt; 1668707Sandreas.hansson@arm.com uint64_t tmp = (uint64_t) bits(base, len - 1, 0) << shiftAmt; 1678707Sandreas.hansson@arm.com if (sign_extend) { 1689095Sandreas.hansson@arm.com int sign_bit = bits(tmp, len + shiftAmt - 1); 1698707Sandreas.hansson@arm.com tmp = sign_bit ? (tmp | ~mask(len + shiftAmt)) : tmp; 1708707Sandreas.hansson@arm.com } 1718707Sandreas.hansson@arm.com return tmp & mask(width); 1728707Sandreas.hansson@arm.com} 1738707Sandreas.hansson@arm.com 1748707Sandreas.hansson@arm.com// Shift Rm by Rs 1758707Sandreas.hansson@arm.comint32_t 1768975Sandreas.hansson@arm.comArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt, 1778975Sandreas.hansson@arm.com uint32_t type, uint32_t cfval) const 1788707Sandreas.hansson@arm.com{ 1798707Sandreas.hansson@arm.com enum ArmShiftType shiftType; 1808707Sandreas.hansson@arm.com shiftType = (enum ArmShiftType) type; 1818707Sandreas.hansson@arm.com 1828707Sandreas.hansson@arm.com switch (shiftType) 1838707Sandreas.hansson@arm.com { 1848707Sandreas.hansson@arm.com case LSL: 1858707Sandreas.hansson@arm.com if (shamt >= 32) 1868711Sandreas.hansson@arm.com return 0; 1878707Sandreas.hansson@arm.com else 1888922Swilliam.wang@arm.com return base << shamt; 1898707Sandreas.hansson@arm.com case LSR: 1908707Sandreas.hansson@arm.com if (shamt >= 32) 1911060SN/A return 0; 1921060SN/A else 1931060SN/A return base >> shamt; 1942292SN/A case ASR: 1951755SN/A if (shamt >= 32) 1961060SN/A return (base >> 31) | -((base & (1 << 31)) >> 31); 1971060SN/A else 1982292SN/A return (base >> shamt) | -((base & (1 << 31)) >> shamt); 1991755SN/A case ROR: 2002292SN/A shamt = shamt & 0x1f; 2012292SN/A if (shamt == 0) 2021060SN/A return base; 2032292SN/A else 2045336Shines@cs.fsu.edu return (base << (32 - shamt)) | (base >> shamt); 2051060SN/A default: 2061060SN/A ccprintf(std::cerr, "Unhandled shift type\n"); 2072292SN/A exit(1); 2081060SN/A break; 2091060SN/A } 2102292SN/A return 0; 2119180Sandreas.hansson@arm.com} 2121060SN/A 2131060SN/A 2149179Sandreas.hansson@arm.com// Generate C for a shift by immediate 2151060SN/Abool 2169179Sandreas.hansson@arm.comArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt, 2171060SN/A uint32_t type, uint32_t cfval) const 2181060SN/A{ 2192292SN/A enum ArmShiftType shiftType; 2201060SN/A shiftType = (enum ArmShiftType) type; 2211060SN/A 2221060SN/A switch (shiftType) 2231060SN/A { 2241060SN/A case LSL: 2251060SN/A if (shamt == 0) 2262829Sksewell@umich.edu return cfval; 2272829Sksewell@umich.edu else 2282829Sksewell@umich.edu return (base >> (32 - shamt)) & 1; 2292829Sksewell@umich.edu case LSR: 2306221Snate@binkert.org if (shamt == 0) 2312829Sksewell@umich.edu return (base >> 31); 2322829Sksewell@umich.edu else 2332829Sksewell@umich.edu return (base >> (shamt - 1)) & 1; 2342829Sksewell@umich.edu case ASR: 2352829Sksewell@umich.edu if (shamt == 0) 2362829Sksewell@umich.edu return (base >> 31); 2372829Sksewell@umich.edu else 2382829Sksewell@umich.edu return (base >> (shamt - 1)) & 1; 2392829Sksewell@umich.edu case ROR: 2402829Sksewell@umich.edu shamt = shamt & 0x1f; 2412829Sksewell@umich.edu if (shamt == 0) 2422829Sksewell@umich.edu return (base & 1); // RRX 2432829Sksewell@umich.edu else 2442829Sksewell@umich.edu return (base >> (shamt - 1)) & 1; 2452829Sksewell@umich.edu default: 2465336Shines@cs.fsu.edu ccprintf(std::cerr, "Unhandled shift type\n"); 2472829Sksewell@umich.edu exit(1); 2482829Sksewell@umich.edu break; 2492829Sksewell@umich.edu } 2506221Snate@binkert.org return 0; 2519180Sandreas.hansson@arm.com} 2522829Sksewell@umich.edu 2532829Sksewell@umich.edu 2542829Sksewell@umich.edu// Generate C for a shift by Rs 2555606Snate@binkert.orgbool 2569179Sandreas.hansson@arm.comArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt, 2578518Sgeoffrey.blake@arm.com uint32_t type, uint32_t cfval) const 2589179Sandreas.hansson@arm.com{ 2598518Sgeoffrey.blake@arm.com enum ArmShiftType shiftType; 2608518Sgeoffrey.blake@arm.com shiftType = (enum ArmShiftType) type; 2618518Sgeoffrey.blake@arm.com 2628518Sgeoffrey.blake@arm.com if (shamt == 0) 2638518Sgeoffrey.blake@arm.com return cfval; 2648518Sgeoffrey.blake@arm.com 2658518Sgeoffrey.blake@arm.com switch (shiftType) 2668518Sgeoffrey.blake@arm.com { 2678518Sgeoffrey.blake@arm.com case LSL: 2688518Sgeoffrey.blake@arm.com if (shamt > 32) 2698518Sgeoffrey.blake@arm.com return 0; 2702829Sksewell@umich.edu else 2712829Sksewell@umich.edu return (base >> (32 - shamt)) & 1; 2722829Sksewell@umich.edu case LSR: 2736221Snate@binkert.org if (shamt > 32) 2746221Snate@binkert.org return 0; 2752829Sksewell@umich.edu else 2762829Sksewell@umich.edu return (base >> (shamt - 1)) & 1; 2772829Sksewell@umich.edu case ASR: 2782829Sksewell@umich.edu if (shamt > 32) 2792829Sksewell@umich.edu shamt = 32; 2802829Sksewell@umich.edu return (base >> (shamt - 1)) & 1; 2812829Sksewell@umich.edu case ROR: 2822829Sksewell@umich.edu shamt = shamt & 0x1f; 2832875Sksewell@umich.edu if (shamt == 0) 2842875Sksewell@umich.edu shamt = 32; 2852875Sksewell@umich.edu return (base >> (shamt - 1)) & 1; 2863221Sktlim@umich.edu default: 2876221Snate@binkert.org ccprintf(std::cerr, "Unhandled shift type\n"); 2882875Sksewell@umich.edu exit(1); 2893221Sktlim@umich.edu break; 2903221Sktlim@umich.edu } 2913221Sktlim@umich.edu return 0; 2922875Sksewell@umich.edu} 2932875Sksewell@umich.edu 2942875Sksewell@umich.eduvoid 2952875Sksewell@umich.eduArmStaticInst::printIntReg(std::ostream &os, RegIndex reg_idx) const 2962875Sksewell@umich.edu{ 2972875Sksewell@umich.edu if (aarch64) { 2982875Sksewell@umich.edu if (reg_idx == INTREG_UREG0) 2992875Sksewell@umich.edu ccprintf(os, "ureg0"); 3002875Sksewell@umich.edu else if (reg_idx == INTREG_SPX) 3012875Sksewell@umich.edu ccprintf(os, "%s%s", (intWidth == 32) ? "w" : "", "sp"); 3022875Sksewell@umich.edu else if (reg_idx == INTREG_X31) 3032875Sksewell@umich.edu ccprintf(os, "%szr", (intWidth == 32) ? "w" : "x"); 3042875Sksewell@umich.edu else 3053221Sktlim@umich.edu ccprintf(os, "%s%d", (intWidth == 32) ? "w" : "x", reg_idx); 3063221Sktlim@umich.edu } else { 3073221Sktlim@umich.edu switch (reg_idx) { 3082875Sksewell@umich.edu case PCReg: 3095336Shines@cs.fsu.edu ccprintf(os, "pc"); 3102875Sksewell@umich.edu break; 3112875Sksewell@umich.edu case StackPointerReg: 3122875Sksewell@umich.edu ccprintf(os, "sp"); 3136221Snate@binkert.org break; 3149180Sandreas.hansson@arm.com case FramePointerReg: 3152875Sksewell@umich.edu ccprintf(os, "fp"); 3162875Sksewell@umich.edu break; 3172875Sksewell@umich.edu case ReturnAddressReg: 3185606Snate@binkert.org ccprintf(os, "lr"); 3199179Sandreas.hansson@arm.com break; 3202875Sksewell@umich.edu default: 3215606Snate@binkert.org ccprintf(os, "r%d", reg_idx); 3229179Sandreas.hansson@arm.com break; 3232875Sksewell@umich.edu } 3242875Sksewell@umich.edu } 3252875Sksewell@umich.edu} 3266221Snate@binkert.org 3276221Snate@binkert.orgvoid 3282875Sksewell@umich.eduArmStaticInst::printFloatReg(std::ostream &os, RegIndex reg_idx) const 3292875Sksewell@umich.edu{ 3302875Sksewell@umich.edu ccprintf(os, "f%d", reg_idx); 3312875Sksewell@umich.edu} 3322875Sksewell@umich.edu 3332875Sksewell@umich.eduvoid 3342875Sksewell@umich.eduArmStaticInst::printCCReg(std::ostream &os, RegIndex reg_idx) const 3352875Sksewell@umich.edu{ 3369444SAndreas.Sandberg@ARM.com ccprintf(os, "cc_%s", ArmISA::ccRegName[reg_idx]); 3379444SAndreas.Sandberg@ARM.com} 3389444SAndreas.Sandberg@ARM.com 3399444SAndreas.Sandberg@ARM.comvoid 3409444SAndreas.Sandberg@ARM.comArmStaticInst::printMiscReg(std::ostream &os, RegIndex reg_idx) const 3419444SAndreas.Sandberg@ARM.com{ 3429444SAndreas.Sandberg@ARM.com assert(reg_idx < NUM_MISCREGS); 3439444SAndreas.Sandberg@ARM.com ccprintf(os, "%s", ArmISA::miscRegName[reg_idx]); 3449444SAndreas.Sandberg@ARM.com} 3459444SAndreas.Sandberg@ARM.com 3469444SAndreas.Sandberg@ARM.comvoid 3479444SAndreas.Sandberg@ARM.comArmStaticInst::printMnemonic(std::ostream &os, 3489444SAndreas.Sandberg@ARM.com const std::string &suffix, 3499444SAndreas.Sandberg@ARM.com bool withPred, 3509444SAndreas.Sandberg@ARM.com bool withCond64, 3519444SAndreas.Sandberg@ARM.com ConditionCode cond64) const 3529444SAndreas.Sandberg@ARM.com{ 3539444SAndreas.Sandberg@ARM.com os << " " << mnemonic; 3549444SAndreas.Sandberg@ARM.com if (withPred && !aarch64) { 3559444SAndreas.Sandberg@ARM.com printCondition(os, machInst.condCode); 3569444SAndreas.Sandberg@ARM.com os << suffix; 3579444SAndreas.Sandberg@ARM.com } else if (withCond64) { 3589444SAndreas.Sandberg@ARM.com os << "."; 3599444SAndreas.Sandberg@ARM.com printCondition(os, cond64); 3609444SAndreas.Sandberg@ARM.com os << suffix; 3619444SAndreas.Sandberg@ARM.com } 3629444SAndreas.Sandberg@ARM.com if (machInst.bigThumb) 3631060SN/A os << ".w"; 3642292SN/A os << " "; 3655595Sgblack@eecs.umich.edu} 3662292SN/A 3671755SN/Avoid 3681060SN/AArmStaticInst::printTarget(std::ostream &os, Addr target, 3692292SN/A const SymbolTable *symtab) const 3705595Sgblack@eecs.umich.edu{ 3711684SN/A Addr symbolAddr; 3725358Sgblack@eecs.umich.edu std::string symbol; 3735358Sgblack@eecs.umich.edu 3745358Sgblack@eecs.umich.edu if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) { 3755358Sgblack@eecs.umich.edu ccprintf(os, "<%s", symbol); 3765358Sgblack@eecs.umich.edu if (symbolAddr != target) 3775358Sgblack@eecs.umich.edu ccprintf(os, "+%d>", target - symbolAddr); 3785358Sgblack@eecs.umich.edu else 3795358Sgblack@eecs.umich.edu ccprintf(os, ">"); 3805358Sgblack@eecs.umich.edu } else { 3815358Sgblack@eecs.umich.edu ccprintf(os, "%#x", target); 3825358Sgblack@eecs.umich.edu } 3835358Sgblack@eecs.umich.edu} 3845358Sgblack@eecs.umich.edu 3855358Sgblack@eecs.umich.eduvoid 3865358Sgblack@eecs.umich.eduArmStaticInst::printCondition(std::ostream &os, 3875358Sgblack@eecs.umich.edu unsigned code, 3882292SN/A bool noImplicit) const 3892292SN/A{ 3902292SN/A switch (code) { 3911684SN/A case COND_EQ: 3921684SN/A os << "eq"; 3932292SN/A break; 3941060SN/A case COND_NE: 3951060SN/A os << "ne"; 3969427SAndreas.Sandberg@ARM.com break; 3979427SAndreas.Sandberg@ARM.com case COND_CS: 3982834Sksewell@umich.edu os << "cs"; 3992834Sksewell@umich.edu break; 4002834Sksewell@umich.edu case COND_CC: 4012834Sksewell@umich.edu os << "cc"; 4022829Sksewell@umich.edu break; 4036221Snate@binkert.org case COND_MI: 4042875Sksewell@umich.edu os << "mi"; 4052875Sksewell@umich.edu break; 4066221Snate@binkert.org case COND_PL: 4072829Sksewell@umich.edu os << "pl"; 4082292SN/A break; 4096221Snate@binkert.org case COND_VS: 4101060SN/A os << "vs"; 4112292SN/A break; 4126221Snate@binkert.org case COND_VC: 4132292SN/A os << "vc"; 4142292SN/A break; 4158834Satgutier@umich.edu case COND_HI: 4168834Satgutier@umich.edu os << "hi"; 4178834Satgutier@umich.edu break; 4188834Satgutier@umich.edu case COND_LS: 4192292SN/A os << "ls"; 4202292SN/A break; 4219180Sandreas.hansson@arm.com case COND_GE: 4222292SN/A os << "ge"; 4232292SN/A break; 4246221Snate@binkert.org case COND_LT: 4252292SN/A os << "lt"; 4262292SN/A break; 4273221Sktlim@umich.edu case COND_GT: 4282292SN/A os << "gt"; 4299180Sandreas.hansson@arm.com break; 4309180Sandreas.hansson@arm.com case COND_LE: 4312292SN/A os << "le"; 4322292SN/A break; 4332292SN/A case COND_AL: 4342292SN/A // This one is implicit. 4356221Snate@binkert.org if (noImplicit) 4362292SN/A os << "al"; 4372292SN/A break; 4386221Snate@binkert.org case COND_UC: 4392292SN/A // Unconditional. 4402292SN/A if (noImplicit) 4412292SN/A os << "uc"; 4422292SN/A break; 4432292SN/A default: 4442292SN/A panic("Unrecognized condition code %d.\n", code); 4452292SN/A } 4469444SAndreas.Sandberg@ARM.com} 4479444SAndreas.Sandberg@ARM.com 4489444SAndreas.Sandberg@ARM.comvoid 4492864Sktlim@umich.eduArmStaticInst::printMemSymbol(std::ostream &os, 4502864Sktlim@umich.edu const SymbolTable *symtab, 4512864Sktlim@umich.edu const std::string &prefix, 4522864Sktlim@umich.edu const Addr addr, 4532864Sktlim@umich.edu const std::string &suffix) const 4542864Sktlim@umich.edu{ 4552864Sktlim@umich.edu Addr symbolAddr; 4565595Sgblack@eecs.umich.edu std::string symbol; 4575595Sgblack@eecs.umich.edu if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) { 4582292SN/A ccprintf(os, "%s%s", prefix, symbol); 4596221Snate@binkert.org if (symbolAddr != addr) 4602292SN/A ccprintf(os, "+%d", addr - symbolAddr); 4612843Sktlim@umich.edu ccprintf(os, suffix); 4622843Sktlim@umich.edu } 4639342SAndreas.Sandberg@arm.com} 4642843Sktlim@umich.edu 4652843Sktlim@umich.eduvoid 4669342SAndreas.Sandberg@arm.comArmStaticInst::printShiftOperand(std::ostream &os, 4672292SN/A IntRegIndex rm, 4689444SAndreas.Sandberg@ARM.com bool immShift, 4699444SAndreas.Sandberg@ARM.com uint32_t shiftAmt, 4709444SAndreas.Sandberg@ARM.com IntRegIndex rs, 4719444SAndreas.Sandberg@ARM.com ArmShiftType type) const 4729444SAndreas.Sandberg@ARM.com{ 4739444SAndreas.Sandberg@ARM.com bool firstOp = false; 4749444SAndreas.Sandberg@ARM.com 4759444SAndreas.Sandberg@ARM.com if (rm != INTREG_ZERO) { 4762843Sktlim@umich.edu printIntReg(os, rm); 4772843Sktlim@umich.edu } 4782843Sktlim@umich.edu 4792316SN/A bool done = false; 4802348SN/A 4812843Sktlim@umich.edu if ((type == LSR || type == ASR) && immShift && shiftAmt == 0) 4821060SN/A shiftAmt = 32; 4831060SN/A 4842316SN/A switch (type) { 4852316SN/A case LSL: 4861060SN/A if (immShift && shiftAmt == 0) { 4875595Sgblack@eecs.umich.edu done = true; 4887684Sgblack@eecs.umich.edu break; 4895595Sgblack@eecs.umich.edu } 4905702Ssaidi@eecs.umich.edu if (!firstOp) 4916221Snate@binkert.org os << ", "; 4925702Ssaidi@eecs.umich.edu os << "LSL"; 4936221Snate@binkert.org break; 4945702Ssaidi@eecs.umich.edu case LSR: 4955595Sgblack@eecs.umich.edu if (!firstOp) 4965595Sgblack@eecs.umich.edu os << ", "; 4975595Sgblack@eecs.umich.edu os << "LSR"; 4985595Sgblack@eecs.umich.edu break; 4995595Sgblack@eecs.umich.edu case ASR: 5005595Sgblack@eecs.umich.edu if (!firstOp) 5015595Sgblack@eecs.umich.edu os << ", "; 5025595Sgblack@eecs.umich.edu os << "ASR"; 5035595Sgblack@eecs.umich.edu break; 5041060SN/A case ROR: 5051060SN/A if (immShift && shiftAmt == 0) { 5061060SN/A if (!firstOp) 5071060SN/A os << ", "; 5081060SN/A os << "RRX"; 5091060SN/A done = true; 5102348SN/A break; 5115595Sgblack@eecs.umich.edu } 5125595Sgblack@eecs.umich.edu if (!firstOp) 5136221Snate@binkert.org os << ", "; 5145595Sgblack@eecs.umich.edu os << "ROR"; 5155595Sgblack@eecs.umich.edu break; 5165595Sgblack@eecs.umich.edu default: 5175595Sgblack@eecs.umich.edu panic("Tried to disassemble unrecognized shift type.\n"); 5186221Snate@binkert.org } 5195595Sgblack@eecs.umich.edu if (!done) { 5205595Sgblack@eecs.umich.edu if (!firstOp) 5216221Snate@binkert.org os << " "; 5226221Snate@binkert.org if (immShift) 5235595Sgblack@eecs.umich.edu os << "#" << shiftAmt; 5245595Sgblack@eecs.umich.edu else 5255595Sgblack@eecs.umich.edu printIntReg(os, rs); 5265595Sgblack@eecs.umich.edu } 5275595Sgblack@eecs.umich.edu} 5286221Snate@binkert.org 5295595Sgblack@eecs.umich.eduvoid 5301060SN/AArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os, 5311060SN/A IntRegIndex rm, ArmExtendType type, 5323781Sgblack@eecs.umich.edu int64_t shiftAmt) const 5331060SN/A{ 5343781Sgblack@eecs.umich.edu if (!firstOperand) 5352455SN/A ccprintf(os, ", "); 5361060SN/A printIntReg(os, rm); 5371060SN/A if (type == UXTX && shiftAmt == 0) 5383781Sgblack@eecs.umich.edu return; 5391060SN/A switch (type) { 5403781Sgblack@eecs.umich.edu case UXTB: ccprintf(os, ", UXTB"); 5412455SN/A break; 5426221Snate@binkert.org case UXTH: ccprintf(os, ", UXTH"); 5431060SN/A break; 5446314Sgblack@eecs.umich.edu case UXTW: ccprintf(os, ", UXTW"); 5452292SN/A break; 5466221Snate@binkert.org case UXTX: ccprintf(os, ", LSL"); 5472292SN/A break; 5482348SN/A case SXTB: ccprintf(os, ", SXTB"); 5492348SN/A break; 5502348SN/A case SXTH: ccprintf(os, ", SXTH"); 5512348SN/A break; 5522348SN/A case SXTW: ccprintf(os, ", SXTW"); 5536221Snate@binkert.org break; 5542292SN/A case SXTX: ccprintf(os, ", SXTW"); 5556314Sgblack@eecs.umich.edu break; 5562292SN/A } 5576221Snate@binkert.org if (type == UXTX || shiftAmt) 5582292SN/A ccprintf(os, " #%d", shiftAmt); 5597720Sgblack@eecs.umich.edu} 5607720Sgblack@eecs.umich.edu 5617720Sgblack@eecs.umich.eduvoid 5627720Sgblack@eecs.umich.eduArmStaticInst::printDataInst(std::ostream &os, bool withImm, 5637720Sgblack@eecs.umich.edu bool immShift, bool s, IntRegIndex rd, IntRegIndex rn, 5647720Sgblack@eecs.umich.edu IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt, 5652348SN/A ArmShiftType type, uint64_t imm) const 5667720Sgblack@eecs.umich.edu{ 5672292SN/A printMnemonic(os, s ? "s" : ""); 5684636Sgblack@eecs.umich.edu bool firstOp = true; 5697720Sgblack@eecs.umich.edu 5704636Sgblack@eecs.umich.edu // Destination 5712348SN/A if (rd != INTREG_ZERO) { 5727720Sgblack@eecs.umich.edu firstOp = false; 5732756Sksewell@umich.edu printIntReg(os, rd); 5745595Sgblack@eecs.umich.edu } 5755595Sgblack@eecs.umich.edu 5765595Sgblack@eecs.umich.edu // Source 1. 5775595Sgblack@eecs.umich.edu if (rn != INTREG_ZERO) { 5786221Snate@binkert.org if (!firstOp) 5795595Sgblack@eecs.umich.edu os << ", "; 5801060SN/A firstOp = false; 5811060SN/A printIntReg(os, rn); 5821060SN/A } 5832292SN/A 5841060SN/A if (!firstOp) 5851060SN/A os << ", "; 5868834Satgutier@umich.edu if (withImm) { 5871060SN/A ccprintf(os, "#%ld", imm); 5882325SN/A } else { 5892325SN/A printShiftOperand(os, rm, immShift, shiftAmt, rs, type); 5901060SN/A } 5911061SN/A} 5921060SN/A 5932935Sksewell@umich.edustd::string 5942935Sksewell@umich.eduArmStaticInst::generateDisassembly(Addr pc, 5956221Snate@binkert.org const SymbolTable *symtab) const 5961060SN/A{ 5971062SN/A std::stringstream ss; 5986221Snate@binkert.org printMnemonic(ss); 5992292SN/A return ss.str(); 6002348SN/A} 6016221Snate@binkert.org 6022292SN/A 6032348SN/AFault 6042292SN/AArmStaticInst::advSIMDFPAccessTrap64(ExceptionLevel el) const 6051062SN/A{ 6062348SN/A switch (el) { 6071060SN/A case EL1: 6081060SN/A return std::make_shared<SupervisorTrap>(machInst, 0x1E00000, 6091060SN/A EC_TRAPPED_SIMD_FP); 6105737Scws3k@cs.virginia.edu case EL2: 6115737Scws3k@cs.virginia.edu return std::make_shared<HypervisorTrap>(machInst, 0x1E00000, 6125737Scws3k@cs.virginia.edu EC_TRAPPED_SIMD_FP); 6135737Scws3k@cs.virginia.edu case EL3: 6145737Scws3k@cs.virginia.edu return std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000, 6151060SN/A EC_TRAPPED_SIMD_FP); 6162292SN/A 6171060SN/A default: 6182292SN/A panic("Illegal EL in advSIMDFPAccessTrap64\n"); 6192292SN/A } 6202292SN/A} 6212292SN/A 6222292SN/A 6232325SN/AFault 6242348SN/AArmStaticInst::checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const 6252348SN/A{ 6262348SN/A const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el; 6272292SN/A 6282325SN/A if (ArmSystem::haveVirtualization(tc) && el <= EL2) { 6292292SN/A HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL2); 6302325SN/A if (cptrEnCheck.tfp) 6312325SN/A return advSIMDFPAccessTrap64(EL2); 6322292SN/A } 6332292SN/A 6342292SN/A if (ArmSystem::haveSecurity(tc)) { 6351060SN/A HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3); 6361060SN/A if (cptrEnCheck.tfp) 6371060SN/A return advSIMDFPAccessTrap64(EL3); 6381060SN/A } 6391060SN/A 6401060SN/A return NoFault; 6411060SN/A} 6421060SN/A 6431060SN/AFault 6441060SN/AArmStaticInst::checkFPAdvSIMDEnabled64(ThreadContext *tc, 6451060SN/A CPSR cpsr, CPACR cpacr) const 6461060SN/A{ 6471060SN/A const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el; 6481060SN/A if ((el == EL0 && cpacr.fpen != 0x3) || 6491060SN/A (el == EL1 && !(cpacr.fpen & 0x1))) 6501060SN/A return advSIMDFPAccessTrap64(EL1); 6511060SN/A 6521060SN/A return checkFPAdvSIMDTrap64(tc, cpsr); 6531060SN/A} 6541060SN/A 6551060SN/AFault 6561060SN/AArmStaticInst::checkAdvSIMDOrFPEnabled32(ThreadContext *tc, 6571060SN/A CPSR cpsr, CPACR cpacr, 6582292SN/A NSACR nsacr, FPEXC fpexc, 6592292SN/A bool fpexc_check, bool advsimd) const 6602292SN/A{ 6612292SN/A const bool have_virtualization = ArmSystem::haveVirtualization(tc); 6621060SN/A const bool have_security = ArmSystem::haveSecurity(tc); 6631060SN/A const bool is_secure = inSecureState(tc); 6641060SN/A const ExceptionLevel cur_el = opModeToEL(currOpMode(tc)); 6651060SN/A 6662292SN/A if (cur_el == EL0 && ELIs64(tc, EL1)) 6676221Snate@binkert.org return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr); 6682292SN/A 6692292SN/A uint8_t cpacr_cp10 = cpacr.cp10; 6702292SN/A bool cpacr_asedis = cpacr.asedis; 6712292SN/A 6729384SAndreas.Sandberg@arm.com if (have_security && !ELIs64(tc, EL3) && !is_secure) { 6736313Sgblack@eecs.umich.edu if (nsacr.nsasedis) 6748707Sandreas.hansson@arm.com cpacr_asedis = true; 6758707Sandreas.hansson@arm.com if (nsacr.cp10 == 0) 6768707Sandreas.hansson@arm.com cpacr_cp10 = 0; 6778707Sandreas.hansson@arm.com } 6788707Sandreas.hansson@arm.com 6798707Sandreas.hansson@arm.com if (cur_el != EL2) { 6801060SN/A if (advsimd && cpacr_asedis) 6812292SN/A return disabledFault(); 6822292SN/A 6832292SN/A if ((cur_el == EL0 && cpacr_cp10 != 0x3) || 6842292SN/A (cur_el != EL0 && !(cpacr_cp10 & 0x1))) 6852292SN/A return disabledFault(); 6862292SN/A } 6872292SN/A 6882292SN/A if (fpexc_check && !fpexc.en) 6892292SN/A return disabledFault(); 6902292SN/A 6912292SN/A // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap -- 6922292SN/A 6931060SN/A if (have_virtualization && !is_secure && ELIs64(tc, EL2)) 6941060SN/A return checkFPAdvSIMDTrap64(tc, cpsr); 6951060SN/A 6961061SN/A if (have_virtualization && !is_secure) { 6971060SN/A HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR); 6981061SN/A bool hcptr_cp10 = hcptr.tcp10; 6991060SN/A bool hcptr_tase = hcptr.tase; 7001061SN/A 7011060SN/A if (have_security && !ELIs64(tc, EL3) && !is_secure) { 7021061SN/A if (nsacr.nsasedis) 7031060SN/A hcptr_tase = true; 7041061SN/A if (nsacr.cp10) 7051060SN/A hcptr_cp10 = true; 7061060SN/A } 7071060SN/A 7081060SN/A if ((advsimd && hcptr_tase) || hcptr_cp10) { 7091060SN/A const uint32_t iss = advsimd ? (1 << 5) : 0xA; 7101060SN/A if (cur_el == EL2) { 7111060SN/A return std::make_shared<UndefinedInstruction>( 7121060SN/A machInst, iss, 7131060SN/A EC_TRAPPED_HCPTR, mnemonic); 7141060SN/A } else { 7151060SN/A return std::make_shared<HypervisorTrap>( 7161060SN/A machInst, iss, 7171060SN/A EC_TRAPPED_HCPTR); 7181060SN/A } 7191060SN/A 7201060SN/A } 7212348SN/A } 7222348SN/A 7232348SN/A if (have_security && ELIs64(tc, EL3)) { 7242348SN/A HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3); 7252348SN/A if (cptrEnCheck.tfp) 7262325SN/A return advSIMDFPAccessTrap64(EL3); 7271060SN/A } 7282348SN/A 7292348SN/A return NoFault; 7302325SN/A} 7312292SN/A 7322348SN/A 7332325SN/Astatic uint8_t 7342325SN/AgetRestoredITBits(ThreadContext *tc, CPSR spsr) 7352292SN/A{ 7362348SN/A // See: shared/functions/system/RestoredITBits in the ARM ARM 7372325SN/A 7382325SN/A const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode); 7392292SN/A const uint8_t it = itState(spsr); 7402292SN/A 7412292SN/A if (!spsr.t || spsr.il) 7422260SN/A return 0; 7435807Snate@binkert.org 7445807Snate@binkert.org // The IT bits are forced to zero when they are set to a reserved 7452292SN/A // value. 7466221Snate@binkert.org if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0) 7472292SN/A return 0; 7482292SN/A 7492680Sktlim@umich.edu const bool itd = el == EL2 ? 7506221Snate@binkert.org ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd : 7516221Snate@binkert.org ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd; 7521681SN/A 7532680Sktlim@umich.edu // The IT bits are forced to zero when returning to A32 state, or 7542190SN/A // when returning to an EL with the ITD bit set to 1, and the IT 7552190SN/A // bits are describing a multi-instruction block. 7562292SN/A if (itd && bits(it, 2, 0) != 0) 7573093Sksewell@umich.edu return 0; 7581060SN/A 7592348SN/A return it; 7602348SN/A} 7612348SN/A 7622348SN/Astatic bool 7638733Sgeoffrey.blake@arm.comillegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr) 7642316SN/A{ 7652292SN/A const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode; 7661060SN/A if (badMode(mode)) 7671060SN/A return true; 7689342SAndreas.Sandberg@arm.com 7699342SAndreas.Sandberg@arm.com const OperatingMode cur_mode = (OperatingMode) (uint8_t)cpsr.mode; 7702843Sktlim@umich.edu const ExceptionLevel target_el = opModeToEL(mode); 7712348SN/A if (target_el > opModeToEL(cur_mode)) 7722292SN/A return true; 7732260SN/A 7742292SN/A if (target_el == EL3 && !ArmSystem::haveSecurity(tc)) 7752292SN/A return true; 7761060SN/A 7772292SN/A if (target_el == EL2 && !ArmSystem::haveVirtualization(tc)) 7782292SN/A return true; 7792292SN/A 7802292SN/A if (!spsr.width) { 7819180Sandreas.hansson@arm.com // aarch64 7822292SN/A if (!ArmSystem::highestELIs64(tc)) 7832829Sksewell@umich.edu return true; 7842829Sksewell@umich.edu 7852829Sksewell@umich.edu if (spsr & 0x2) 7862292SN/A return true; 7876221Snate@binkert.org if (target_el == EL0 && spsr.sp) 7882292SN/A return true; 7892292SN/A if (target_el == EL2 && !((SCR)tc->readMiscReg(MISCREG_SCR_EL3)).ns) 7906221Snate@binkert.org return false; 7912292SN/A } else { 7925595Sgblack@eecs.umich.edu return badMode32(mode); 7936974Stjones1@inf.ed.ac.uk } 7947520Sgblack@eecs.umich.edu 7955595Sgblack@eecs.umich.edu return false; 7966974Stjones1@inf.ed.ac.uk} 7976974Stjones1@inf.ed.ac.uk 7985595Sgblack@eecs.umich.eduCPSR 7995595Sgblack@eecs.umich.eduArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const 8005595Sgblack@eecs.umich.edu{ 8016974Stjones1@inf.ed.ac.uk CPSR new_cpsr = 0; 8027520Sgblack@eecs.umich.edu 8035595Sgblack@eecs.umich.edu // gem5 doesn't implement single-stepping, so force the SS bit to 8046974Stjones1@inf.ed.ac.uk // 0. 8056974Stjones1@inf.ed.ac.uk new_cpsr.ss = 0; 8065595Sgblack@eecs.umich.edu 8075595Sgblack@eecs.umich.edu if (illegalExceptionReturn(tc, cpsr, spsr)) { 8088707Sandreas.hansson@arm.com new_cpsr.il = 1; 8098850Sandreas.hansson@arm.com } else { 8108707Sandreas.hansson@arm.com new_cpsr.il = spsr.il; 8116974Stjones1@inf.ed.ac.uk if (spsr.width && badMode32((OperatingMode)(uint8_t)spsr.mode)) { 8128850Sandreas.hansson@arm.com new_cpsr.il = 1; 8136974Stjones1@inf.ed.ac.uk } else if (spsr.width) { 8142292SN/A new_cpsr.mode = spsr.mode; 8155999Snate@binkert.org } else { 8162292SN/A new_cpsr.el = spsr.el; 8175999Snate@binkert.org new_cpsr.sp = spsr.sp; 8188627SAli.Saidi@ARM.com } 8198627SAli.Saidi@ARM.com } 8208627SAli.Saidi@ARM.com 8212292SN/A new_cpsr.nz = spsr.nz; 8225999Snate@binkert.org new_cpsr.c = spsr.c; 8238834Satgutier@umich.edu new_cpsr.v = spsr.v; 8248834Satgutier@umich.edu if (new_cpsr.width) { 8252292SN/A // aarch32 8265999Snate@binkert.org const ITSTATE it = getRestoredITBits(tc, spsr); 8272292SN/A new_cpsr.q = spsr.q; 8282292SN/A new_cpsr.ge = spsr.ge; 8292292SN/A new_cpsr.e = spsr.e; 8302292SN/A new_cpsr.aif = spsr.aif; 8312292SN/A new_cpsr.t = spsr.t; 8322292SN/A new_cpsr.it2 = it.top6; 8332292SN/A new_cpsr.it1 = it.bottom2; 8342292SN/A } else { 8357897Shestness@cs.utexas.edu // aarch64 8367897Shestness@cs.utexas.edu new_cpsr.daif = spsr.daif; 8377897Shestness@cs.utexas.edu } 8387897Shestness@cs.utexas.edu 8397897Shestness@cs.utexas.edu return new_cpsr; 8407897Shestness@cs.utexas.edu} 8417897Shestness@cs.utexas.edu 8427897Shestness@cs.utexas.edu 8437897Shestness@cs.utexas.edu 8447897Shestness@cs.utexas.edu} 8451060SN/A