arm.isa revision 7139
16019SN/A// -*- mode:c++ -*- 26019SN/A 37102SN/A// Copyright (c) 2010 ARM Limited 47102SN/A// All rights reserved 57102SN/A// 67102SN/A// The license below extends only to copyright in the software and shall 77102SN/A// not be construed as granting a license to any other intellectual 87102SN/A// property including but not limited to intellectual property relating 97102SN/A// to a hardware implementation of the functionality of the software 107102SN/A// licensed hereunder. You may use the software subject to the license 117102SN/A// terms below provided that you ensure that this notice is replicated 127102SN/A// unmodified and in its entirety in all distributions of the software, 137102SN/A// modified or unmodified, in source code or in binary form. 147102SN/A// 156019SN/A// Copyright (c) 2007-2008 The Florida State University 166019SN/A// All rights reserved. 176019SN/A// 186019SN/A// Redistribution and use in source and binary forms, with or without 196019SN/A// modification, are permitted provided that the following conditions are 206019SN/A// met: redistributions of source code must retain the above copyright 216019SN/A// notice, this list of conditions and the following disclaimer; 226019SN/A// redistributions in binary form must reproduce the above copyright 236019SN/A// notice, this list of conditions and the following disclaimer in the 246019SN/A// documentation and/or other materials provided with the distribution; 256019SN/A// neither the name of the copyright holders nor the names of its 266019SN/A// contributors may be used to endorse or promote products derived from 276019SN/A// this software without specific prior written permission. 286019SN/A// 296019SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 306019SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316019SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 326019SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 336019SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 346019SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 356019SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 366019SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 376019SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 386019SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 396019SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 406019SN/A// 416019SN/A// Authors: Stephen Hines 426019SN/A 436019SN/A//////////////////////////////////////////////////////////////////// 446019SN/A// 456019SN/A// The actual ARM ISA decoder 466019SN/A// -------------------------- 476019SN/A// The following instructions are specified in the ARM ISA 486019SN/A// Specification. Decoding closely follows the style specified 496019SN/A// in the ARM ISA specification document starting with Table B.1 or 3-1 506019SN/A// 516019SN/A// 526310SN/A 537102SN/A0: decode ENCODING { 546268SN/Aformat DataOp { 556268SN/A 0x0: decode SEVEN_AND_FOUR { 566268SN/A 1: decode MISC_OPCODE { 576268SN/A 0x9: decode PREPOST { 586268SN/A 0: decode OPCODE { 596276SN/A 0x0: mul({{ Rn = resTemp = Rm * Rs; }}, none); 606280SN/A 0x1: mla({{ Rn = resTemp = (Rm * Rs) + Rd; }}, none); 616268SN/A 0x2: WarnUnimpl::umall(); 626268SN/A 0x4: umull({{ 636268SN/A resTemp = ((uint64_t)Rm)*((uint64_t)Rs); 646268SN/A Rd = (uint32_t)(resTemp & 0xffffffff); 656268SN/A Rn = (uint32_t)(resTemp >> 32); 666741SN/A }}, llbit); 677102SN/A 0x5: smlal({{ 687102SN/A resTemp = ((int64_t)Rm) * ((int64_t)Rs); 697102SN/A resTemp += (((uint64_t)Rn) << 32) | ((uint64_t)Rd); 706741SN/A Rd = (uint32_t)(resTemp & 0xffffffff); 716741SN/A Rn = (uint32_t)(resTemp >> 32); 726741SN/A }}, llbit); 736268SN/A 0x6: smull({{ 746272SN/A resTemp = ((int64_t)(int32_t)Rm)* 756272SN/A ((int64_t)(int32_t)Rs); 766268SN/A Rd = (int32_t)(resTemp & 0xffffffff); 776268SN/A Rn = (int32_t)(resTemp >> 32); 786741SN/A }}, llbit); 796268SN/A 0x7: umlal({{ 806268SN/A resTemp = ((uint64_t)Rm)*((uint64_t)Rs); 816268SN/A resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd); 826268SN/A Rd = (uint32_t)(resTemp & 0xffffffff); 836268SN/A Rn = (uint32_t)(resTemp >> 32); 846741SN/A }}, llbit); 856019SN/A } 866268SN/A 1: decode PUBWL { 876268SN/A 0x10: WarnUnimpl::swp(); 886268SN/A 0x14: WarnUnimpl::swpb(); 896268SN/A 0x18: WarnUnimpl::strex(); 906268SN/A 0x19: WarnUnimpl::ldrex(); 916019SN/A } 926019SN/A } 937129Sgblack@eecs.umich.edu 0xb, 0xd, 0xf: AddrMode3::addrMode3(); 946019SN/A } 956268SN/A 0: decode IS_MISC { 967139Sgblack@eecs.umich.edu 0: ArmDataProcReg::armDataProcReg(); 976268SN/A 1: decode MISC_OPCODE { 986268SN/A 0x0: decode OPCODE { 996747SN/A 0x8: PredOp::mrs_cpsr({{ 1006747SN/A Rd = (Cpsr | CondCodes) & 0xF8FF03DF; 1016747SN/A }}); 1026751SN/A 0x9: decode USEIMM { 1036751SN/A // The mask field is the same as the RN index. 1046753SN/A 0: PredOp::msr_cpsr_reg({{ 1056753SN/A uint32_t newCpsr = 1066753SN/A cpsrWriteByInstr(Cpsr | CondCodes, 1076753SN/A Rm, RN, false); 1086753SN/A Cpsr = ~CondCodesMask & newCpsr; 1096753SN/A CondCodes = CondCodesMask & newCpsr; 1106753SN/A }}); 1116753SN/A 1: PredImmOp::msr_cpsr_imm({{ 1126751SN/A uint32_t newCpsr = 1136751SN/A cpsrWriteByInstr(Cpsr | CondCodes, 1146751SN/A rotated_imm, RN, false); 1156751SN/A Cpsr = ~CondCodesMask & newCpsr; 1166751SN/A CondCodes = CondCodesMask & newCpsr; 1176751SN/A }}); 1186751SN/A } 1196747SN/A 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }}); 1206751SN/A 0xb: decode USEIMM { 1216751SN/A // The mask field is the same as the RN index. 1226753SN/A 0: PredOp::msr_spsr_reg({{ 1236753SN/A Spsr = spsrWriteByInstr(Spsr, Rm, RN, false); 1246753SN/A }}); 1256753SN/A 1: PredImmOp::msr_spsr_imm({{ 1266751SN/A Spsr = spsrWriteByInstr(Spsr, rotated_imm, 1276751SN/A RN, false); 1286751SN/A }}); 1296751SN/A } 1306268SN/A } 1316268SN/A 0x1: decode OPCODE { 1326268SN/A 0x9: BranchExchange::bx({{ }}); 1336268SN/A 0xb: PredOp::clz({{ 1346402SN/A Rd = ((Rm == 0) ? 32 : (31 - findMsbSet(Rm))); 1356268SN/A }}); 1366268SN/A } 1376268SN/A 0x2: decode OPCODE { 1386268SN/A 0x9: WarnUnimpl::bxj(); 1396268SN/A } 1406268SN/A 0x3: decode OPCODE { 1416268SN/A 0x9: BranchExchange::blx({{ }}, Link); 1426268SN/A } 1436268SN/A 0x5: decode OPCODE { 1446268SN/A 0x8: WarnUnimpl::qadd(); 1456268SN/A 0x9: WarnUnimpl::qsub(); 1466268SN/A 0xa: WarnUnimpl::qdadd(); 1476268SN/A 0xb: WarnUnimpl::qdsub(); 1486268SN/A } 1496268SN/A 0x8: decode OPCODE { 1506741SN/A 0x8: smlabb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>) + Rd; }}, overflow); 1516268SN/A 0x9: WarnUnimpl::smlalbb(); 1526268SN/A 0xa: WarnUnimpl::smlawb(); 1536741SN/A 0xb: smulbb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>); }}, none); 1546268SN/A } 1556268SN/A 0xa: decode OPCODE { 1566741SN/A 0x8: smlatb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>) + Rd; }}, overflow); 1577102SN/A 0x9: smulwb({{ 1587102SN/A Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<15:0>), 47, 16); 1596741SN/A }}, none); 1606268SN/A 0xa: WarnUnimpl::smlaltb(); 1616741SN/A 0xb: smultb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>); }}, none); 1626268SN/A } 1636268SN/A 0xc: decode OPCODE { 1646741SN/A 0x8: smlabt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>) + Rd; }}, overflow); 1656268SN/A 0x9: WarnUnimpl::smlawt(); 1666268SN/A 0xa: WarnUnimpl::smlalbt(); 1676741SN/A 0xb: smulbt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>); }}, none); 1686268SN/A } 1696268SN/A 0xe: decode OPCODE { 1706741SN/A 0x8: smlatt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>) + Rd; }}, overflow); 1717102SN/A 0x9: smulwt({{ 1727102SN/A Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<31:16>), 47, 16); 1736741SN/A }}, none); 1746268SN/A 0xa: WarnUnimpl::smlaltt(); 1756741SN/A 0xb: smultt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>); }}, none); 1766268SN/A } 1776268SN/A } 1786268SN/A } 1796268SN/A } 1806268SN/A 0x1: decode IS_MISC { 1817139Sgblack@eecs.umich.edu 0: ArmDataProcImm::armDataProcImm(); 1826268SN/A 1: decode OPCODE { 1836268SN/A // The following two instructions aren't supposed to be defined 1846741SN/A 0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }}); 1856756SN/A 0x9: decode RN { 1866756SN/A 0: decode IMM { 1876756SN/A 0: PredImmOp::nop({{ ; }}); 1886756SN/A 1: WarnUnimpl::yield(); 1896756SN/A 2: WarnUnimpl::wfe(); 1906756SN/A 3: WarnUnimpl::wfi(); 1916756SN/A 4: WarnUnimpl::sev(); 1926756SN/A } 1936756SN/A default: PredImmOp::msr_i_cpsr({{ 1946756SN/A uint32_t newCpsr = 1956756SN/A cpsrWriteByInstr(Cpsr | CondCodes, 1966756SN/A rotated_imm, RN, false); 1976756SN/A Cpsr = ~CondCodesMask & newCpsr; 1986756SN/A CondCodes = CondCodesMask & newCpsr; 1996756SN/A }}); 2006756SN/A } 2016756SN/A 0xa: PredOp::movt({{ Rd = IMMED_11_0 << 16 | RN << 28 | Rd<15:0>; }}); 2026756SN/A 0xb: PredImmOp::msr_i_spsr({{ 2037102SN/A Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false); 2046741SN/A }}); 2056019SN/A } 2066268SN/A } 2077120Sgblack@eecs.umich.edu 0x2: AddrMode2::addrMode2(True); 2086268SN/A 0x3: decode OPCODE_4 { 2097120Sgblack@eecs.umich.edu 0: AddrMode2::addrMode2(False); 2106269SN/A 1: decode MEDIA_OPCODE { 2116269SN/A 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7: WarnUnimpl::parallel_add_subtract_instructions(); 2126269SN/A 0x8: decode MISC_OPCODE { 2136269SN/A 0x1, 0x9: WarnUnimpl::pkhbt(); 2146269SN/A 0x7: WarnUnimpl::sxtab16(); 2156269SN/A 0xb: WarnUnimpl::sel(); 2166269SN/A 0x5, 0xd: WarnUnimpl::pkhtb(); 2176269SN/A 0x3: WarnUnimpl::sign_zero_extend_add(); 2186269SN/A } 2196269SN/A 0xa, 0xb: decode SHIFT { 2206269SN/A 0x0, 0x2: WarnUnimpl::ssat(); 2216269SN/A 0x1: WarnUnimpl::ssat16(); 2226269SN/A } 2236269SN/A 0xe, 0xf: decode SHIFT { 2246269SN/A 0x0, 0x2: WarnUnimpl::usat(); 2256269SN/A 0x1: WarnUnimpl::usat16(); 2266269SN/A } 2276269SN/A 0x10: decode RN { 2286269SN/A 0xf: decode MISC_OPCODE { 2296269SN/A 0x1: WarnUnimpl::smuad(); 2306269SN/A 0x3: WarnUnimpl::smuadx(); 2316269SN/A 0x5: WarnUnimpl::smusd(); 2326269SN/A 0x7: WarnUnimpl::smusdx(); 2336269SN/A } 2346269SN/A default: decode MISC_OPCODE { 2356269SN/A 0x1: WarnUnimpl::smlad(); 2366269SN/A 0x3: WarnUnimpl::smladx(); 2376269SN/A 0x5: WarnUnimpl::smlsd(); 2386269SN/A 0x7: WarnUnimpl::smlsdx(); 2396269SN/A } 2406269SN/A } 2416269SN/A 0x14: decode MISC_OPCODE { 2426269SN/A 0x1: WarnUnimpl::smlald(); 2436269SN/A 0x3: WarnUnimpl::smlaldx(); 2446269SN/A 0x5: WarnUnimpl::smlsld(); 2456269SN/A 0x7: WarnUnimpl::smlsldx(); 2466269SN/A } 2476269SN/A 0x15: decode RN { 2486269SN/A 0xf: decode MISC_OPCODE { 2496269SN/A 0x1: WarnUnimpl::smmul(); 2506269SN/A 0x3: WarnUnimpl::smmulr(); 2516269SN/A } 2526269SN/A default: decode MISC_OPCODE { 2536269SN/A 0x1: WarnUnimpl::smmla(); 2546269SN/A 0x3: WarnUnimpl::smmlar(); 2556269SN/A 0xd: WarnUnimpl::smmls(); 2566269SN/A 0xf: WarnUnimpl::smmlsr(); 2576269SN/A } 2586269SN/A } 2596269SN/A 0x18: decode RN { 2606269SN/A 0xf: WarnUnimpl::usada8(); 2616269SN/A default: WarnUnimpl::usad8(); 2626269SN/A } 2636269SN/A } 2646268SN/A } 2657134Sgblack@eecs.umich.edu 0x4: ArmMacroMem::armMacroMem(); 2666268SN/A 0x5: decode OPCODE_24 { 2676268SN/A // Branch (and Link) Instructions 2686268SN/A 0: Branch::b({{ }}); 2696268SN/A 1: Branch::bl({{ }}, Link); 2706268SN/A } 2716268SN/A 0x6: decode CPNUM { 2726412SN/A 0xb: decode LOADOP { 2736412SN/A 0x0: WarnUnimpl::fstmx(); 2746412SN/A 0x1: WarnUnimpl::fldmx(); 2756412SN/A } 2766268SN/A } 2776268SN/A 0x7: decode OPCODE_24 { 2786743SN/A 0: decode OPCODE_4 { 2796743SN/A 0: decode CPNUM { 2807105SN/A 0xa, 0xb: decode OPCODE_23_20 { 2817117Sgblack@eecs.umich.edu##include "vfp.isa" 2827105SN/A } 2836743SN/A } // CPNUM 2846743SN/A 1: decode CPNUM { // 27-24=1110,4 ==1 2856743SN/A 1: decode OPCODE_15_12 { 2866743SN/A format FloatOp { 2876268SN/A 0xf: decode OPCODE_23_21 { 2886268SN/A format FloatCmp { 2896268SN/A 0x4: cmf({{ Fn.df }}, {{ Fm.df }}); 2906268SN/A 0x5: cnf({{ Fn.df }}, {{ -Fm.df }}); 2916268SN/A 0x6: cmfe({{ Fn.df }}, {{ Fm.df}}); 2926268SN/A 0x7: cnfe({{ Fn.df }}, {{ -Fm.df}}); 2936019SN/A } 2946019SN/A } 2956268SN/A default: decode OPCODE_23_20 { 2966268SN/A 0x0: decode OPCODE_7 { 2976268SN/A 0: flts({{ Fn.sf = (float) Rd.sw; }}); 2986268SN/A 1: fltd({{ Fn.df = (double) Rd.sw; }}); 2996019SN/A } 3006268SN/A 0x1: decode OPCODE_7 { 3016268SN/A 0: fixs({{ Rd = (uint32_t) Fm.sf; }}); 3026268SN/A 1: fixd({{ Rd = (uint32_t) Fm.df; }}); 3036019SN/A } 3046268SN/A 0x2: wfs({{ Fpsr = Rd; }}); 3056268SN/A 0x3: rfs({{ Rd = Fpsr; }}); 3066268SN/A 0x4: FailUnimpl::wfc(); 3076268SN/A 0x5: FailUnimpl::rfc(); 3086019SN/A } 3096743SN/A } // format FloatOp 3106019SN/A } 3116743SN/A 0xa: decode MISC_OPCODE { 3126743SN/A 0x1: decode MEDIA_OPCODE { 3136743SN/A 0xf: decode RN { 3146743SN/A 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }}); 3156743SN/A 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }}); 3166743SN/A 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }}); 3176743SN/A } 3186743SN/A 0xe: decode RN { 3196743SN/A 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }}); 3206743SN/A 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }}); 3216743SN/A 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }}); 3226743SN/A } 3236743SN/A } // MEDIA_OPCODE (MISC_OPCODE 0x1) 3246743SN/A } // MISC_OPCODE (CPNUM 0xA) 3256759SN/A 0xf: decode RN { 3266759SN/A // Barrriers, Cache Maintence, NOPS 3276759SN/A 7: decode OPCODE_23_21 { 3286759SN/A 0: decode RM { 3296759SN/A 0: decode OPC2 { 3306759SN/A 4: decode OPCODE_20 { 3316759SN/A 0: PredOp::mcr_cp15_nop1({{ }}); // was wfi 3326759SN/A } 3336759SN/A } 3346759SN/A 1: WarnUnimpl::cp15_cache_maint(); 3356759SN/A 4: WarnUnimpl::cp15_par(); 3366759SN/A 5: decode OPC2 { 3376759SN/A 0,1: WarnUnimpl::cp15_cache_maint2(); 3386759SN/A 4: PredOp::cp15_isb({{ ; }}, IsMemBarrier, IsSerializeBefore); 3396759SN/A 6,7: WarnUnimpl::cp15_bp_maint(); 3406759SN/A } 3416759SN/A 6: WarnUnimpl::cp15_cache_maint3(); 3426759SN/A 8: WarnUnimpl::cp15_va_to_pa(); 3436759SN/A 10: decode OPC2 { 3446759SN/A 1,2: WarnUnimpl::cp15_cache_maint3(); 3456759SN/A 4: PredOp::cp15_dsb({{ ; }}, IsMemBarrier, IsSerializeBefore); 3466759SN/A 5: PredOp::cp15_dmb({{ ; }}, IsMemBarrier, IsSerializeBefore); 3476759SN/A } 3486759SN/A 11: WarnUnimpl::cp15_cache_maint4(); 3496759SN/A 13: decode OPC2 { 3506759SN/A 1: decode OPCODE_20 { 3516759SN/A 0: PredOp::mcr_cp15_nop2({{ }}); // was prefetch 3526759SN/A } 3536759SN/A } 3546759SN/A 14: WarnUnimpl::cp15_cache_maint5(); 3556759SN/A } // RM 3566759SN/A } // OPCODE_23_21 CR 3577102SN/A 3586759SN/A // Thread ID and context ID registers 3596759SN/A // Thread ID register needs cheaper access than miscreg 3607102SN/A 13: WarnUnimpl::mcr_mrc_cp15_c7(); 3616759SN/A 3626759SN/A // All the rest 3636759SN/A default: decode OPCODE_20 { 3647102SN/A 0: PredOp::mcr_cp15({{ 3657102SN/A fault = setCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2); 3666759SN/A }}); 3677102SN/A 1: PredOp::mrc_cp15({{ 3687102SN/A fault = readCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2); 3696759SN/A }}); 3706759SN/A } 3717102SN/A } // RN 3726743SN/A } // CPNUM (OP4 == 1) 3736743SN/A } //OPCODE_4 3746743SN/A 3756743SN/A#if FULL_SYSTEM 3767102SN/A 1: PredOp::swi({{ fault = new SupervisorCall; }}, IsSerializeAfter, IsNonSpeculative, IsSyscall); 3776743SN/A#else 3786743SN/A 1: PredOp::swi({{ if (testPredicate(CondCodes, condCode)) 3796743SN/A { 3806743SN/A if (IMMED_23_0) 3816743SN/A xc->syscall(IMMED_23_0); 3826743SN/A else 3836743SN/A xc->syscall(R7); 3846019SN/A } 3856743SN/A }}); 3866743SN/A#endif // FULL_SYSTEM 3876743SN/A } // OPCODE_24 3886743SN/A 3896268SN/A} 3906268SN/A} 3916019SN/A 392