aarch64.isa revision 12523:11d2f59d3b27
15347Ssaidi@eecs.umich.edu// Copyright (c) 2011-2016 ARM Limited 23395Shsul@eecs.umich.edu// All rights reserved 33395Shsul@eecs.umich.edu// 43395Shsul@eecs.umich.edu// The license below extends only to copyright in the software and shall 53395Shsul@eecs.umich.edu// not be construed as granting a license to any other intellectual 63395Shsul@eecs.umich.edu// property including but not limited to intellectual property relating 73395Shsul@eecs.umich.edu// to a hardware implementation of the functionality of the software 83395Shsul@eecs.umich.edu// licensed hereunder. You may use the software subject to the license 93395Shsul@eecs.umich.edu// terms below provided that you ensure that this notice is replicated 103395Shsul@eecs.umich.edu// unmodified and in its entirety in all distributions of the software, 113395Shsul@eecs.umich.edu// modified or unmodified, in source code or in binary form. 123395Shsul@eecs.umich.edu// 133395Shsul@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 143395Shsul@eecs.umich.edu// modification, are permitted provided that the following conditions are 153395Shsul@eecs.umich.edu// met: redistributions of source code must retain the above copyright 163395Shsul@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 173395Shsul@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 183395Shsul@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 193395Shsul@eecs.umich.edu// documentation and/or other materials provided with the distribution; 203395Shsul@eecs.umich.edu// neither the name of the copyright holders nor the names of its 213395Shsul@eecs.umich.edu// contributors may be used to endorse or promote products derived from 223395Shsul@eecs.umich.edu// this software without specific prior written permission. 233395Shsul@eecs.umich.edu// 243395Shsul@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 253395Shsul@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 263395Shsul@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 273395Shsul@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 283395Shsul@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 293395Shsul@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 303509Shsul@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 316654Snate@binkert.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 323395Shsul@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 336654Snate@binkert.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 343395Shsul@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 356654Snate@binkert.org// 366654Snate@binkert.org// Authors: Gabe Black 376654Snate@binkert.org// Thomas Grocutt 383395Shsul@eecs.umich.edu// Mbou Eyole 393481Shsul@eecs.umich.edu// Giacomo Gabrielli 403481Shsul@eecs.umich.edu 413481Shsul@eecs.umich.eduoutput header {{ 423481Shsul@eecs.umich.edunamespace Aarch64 435347Ssaidi@eecs.umich.edu{ 443481Shsul@eecs.umich.edu StaticInstPtr decodeDataProcImm(ExtMachInst machInst); 453681Sktlim@umich.edu StaticInstPtr decodeBranchExcSys(ExtMachInst machInst); 463681Sktlim@umich.edu StaticInstPtr decodeLoadsStores(ExtMachInst machInst); 473681Sktlim@umich.edu StaticInstPtr decodeDataProcReg(ExtMachInst machInst); 485347Ssaidi@eecs.umich.edu 495869Sksewell@umich.edu template <typename DecoderFeatures> 505869Sksewell@umich.edu StaticInstPtr decodeFpAdvSIMD(ExtMachInst machInst); 515869Sksewell@umich.edu StaticInstPtr decodeFp(ExtMachInst machInst); 525869Sksewell@umich.edu template <typename DecoderFeatures> 535869Sksewell@umich.edu StaticInstPtr decodeAdvSIMD(ExtMachInst machInst); 543481Shsul@eecs.umich.edu StaticInstPtr decodeAdvSIMDScalar(ExtMachInst machInst); 555347Ssaidi@eecs.umich.edu 563481Shsul@eecs.umich.edu StaticInstPtr decodeGem5Ops(ExtMachInst machInst); 573481Shsul@eecs.umich.edu} 583481Shsul@eecs.umich.edu}}; 593481Shsul@eecs.umich.edu 603481Shsul@eecs.umich.eduoutput decoder {{ 613481Shsul@eecs.umich.edunamespace Aarch64 625369Ssaidi@eecs.umich.edu{ 633481Shsul@eecs.umich.edu StaticInstPtr 645347Ssaidi@eecs.umich.edu decodeDataProcImm(ExtMachInst machInst) 653481Shsul@eecs.umich.edu { 663481Shsul@eecs.umich.edu IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 673481Shsul@eecs.umich.edu IntRegIndex rdsp = makeSP(rd); 683481Shsul@eecs.umich.edu IntRegIndex rdzr = makeZero(rd); 693481Shsul@eecs.umich.edu IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 703481Shsul@eecs.umich.edu IntRegIndex rnsp = makeSP(rn); 713481Shsul@eecs.umich.edu 723395Shsul@eecs.umich.edu uint8_t opc = bits(machInst, 30, 29); 733395Shsul@eecs.umich.edu bool sf = bits(machInst, 31); 743395Shsul@eecs.umich.edu bool n = bits(machInst, 22); 754167Sbinkertn@umich.edu uint8_t immr = bits(machInst, 21, 16); 763395Shsul@eecs.umich.edu uint8_t imms = bits(machInst, 15, 10); 773395Shsul@eecs.umich.edu switch (bits(machInst, 25, 23)) { 783395Shsul@eecs.umich.edu case 0x0: 793511Shsul@eecs.umich.edu case 0x1: 803395Shsul@eecs.umich.edu { 813395Shsul@eecs.umich.edu uint64_t immlo = bits(machInst, 30, 29); 823395Shsul@eecs.umich.edu uint64_t immhi = bits(machInst, 23, 5); 835211Ssaidi@eecs.umich.edu uint64_t imm = (immlo << 0) | (immhi << 2); 845211Ssaidi@eecs.umich.edu if (bits(machInst, 31) == 0) 853395Shsul@eecs.umich.edu return new AdrXImm(machInst, rdzr, INTREG_ZERO, sext<21>(imm)); 863395Shsul@eecs.umich.edu else 873395Shsul@eecs.umich.edu return new AdrpXImm(machInst, rdzr, INTREG_ZERO, 885370Ssaidi@eecs.umich.edu sext<33>(imm << 12)); 896654Snate@binkert.org } 905370Ssaidi@eecs.umich.edu case 0x2: 915371Shsul@eecs.umich.edu case 0x3: 926654Snate@binkert.org { 935370Ssaidi@eecs.umich.edu uint32_t imm12 = bits(machInst, 21, 10); 943395Shsul@eecs.umich.edu uint8_t shift = bits(machInst, 23, 22); 953395Shsul@eecs.umich.edu uint32_t imm; 963481Shsul@eecs.umich.edu if (shift == 0x0) 973481Shsul@eecs.umich.edu imm = imm12 << 0; 986144Sksewell@umich.edu else if (shift == 0x1) 996144Sksewell@umich.edu imm = imm12 << 12; 1006144Sksewell@umich.edu else 1016144Sksewell@umich.edu return new Unknown64(machInst); 1026641Sksewell@umich.edu switch (opc) { 1036641Sksewell@umich.edu case 0x0: 1046641Sksewell@umich.edu return new AddXImm(machInst, rdsp, rnsp, imm); 1056641Sksewell@umich.edu case 0x1: 1063481Shsul@eecs.umich.edu return new AddXImmCc(machInst, rdzr, rnsp, imm); 1073481Shsul@eecs.umich.edu case 0x2: 1083481Shsul@eecs.umich.edu return new SubXImm(machInst, rdsp, rnsp, imm); 1093481Shsul@eecs.umich.edu case 0x3: 1103481Shsul@eecs.umich.edu return new SubXImmCc(machInst, rdzr, rnsp, imm); 1115361Srstrong@cs.ucsd.edu } 1125369Ssaidi@eecs.umich.edu } 1133481Shsul@eecs.umich.edu case 0x4: 1146654Snate@binkert.org { 1153481Shsul@eecs.umich.edu if (!sf && n) 1163481Shsul@eecs.umich.edu return new Unknown64(machInst); 1175369Ssaidi@eecs.umich.edu // len = MSB(n:NOT(imms)), len < 1 is undefined. 1185369Ssaidi@eecs.umich.edu uint8_t len = 0; 1195369Ssaidi@eecs.umich.edu if (n) { 1203481Shsul@eecs.umich.edu len = 6; 1215311Ssaidi@eecs.umich.edu } else if (imms == 0x3f || imms == 0x3e) { 1223481Shsul@eecs.umich.edu return new Unknown64(machInst); 1233395Shsul@eecs.umich.edu } else { 1243395Shsul@eecs.umich.edu len = findMsbSet(imms ^ 0x3f); 1253395Shsul@eecs.umich.edu } 1263395Shsul@eecs.umich.edu // Generate r, s, and size. 1273478Shsul@eecs.umich.edu uint64_t r = bits(immr, len - 1, 0); 1283395Shsul@eecs.umich.edu uint64_t s = bits(imms, len - 1, 0); 1293478Shsul@eecs.umich.edu uint8_t size = 1 << len; 1303395Shsul@eecs.umich.edu if (s == size - 1) 1313395Shsul@eecs.umich.edu return new Unknown64(machInst); 1323478Shsul@eecs.umich.edu // Generate the pattern with s 1s, rotated by r, with size bits. 1336654Snate@binkert.org uint64_t pattern = mask(s + 1); 1343395Shsul@eecs.umich.edu if (r) { 1353478Shsul@eecs.umich.edu pattern = (pattern >> r) | (pattern << (size - r)); 1363395Shsul@eecs.umich.edu pattern &= mask(size); 1373478Shsul@eecs.umich.edu } 1383480Shsul@eecs.umich.edu uint8_t width = sf ? 64 : 32; 1395361Srstrong@cs.ucsd.edu // Replicate that to fill up the immediate. 1405369Ssaidi@eecs.umich.edu for (unsigned i = 1; i < (width / size); i *= 2) 1415361Srstrong@cs.ucsd.edu pattern |= (pattern << (i * size)); 1425361Srstrong@cs.ucsd.edu uint64_t imm = pattern; 1435361Srstrong@cs.ucsd.edu 1445369Ssaidi@eecs.umich.edu switch (opc) { 1455361Srstrong@cs.ucsd.edu case 0x0: 1465361Srstrong@cs.ucsd.edu return new AndXImm(machInst, rdsp, rn, imm); 1475378Ssaidi@eecs.umich.edu case 0x1: 1486654Snate@binkert.org return new OrrXImm(machInst, rdsp, rn, imm); 1495361Srstrong@cs.ucsd.edu case 0x2: 1505361Srstrong@cs.ucsd.edu return new EorXImm(machInst, rdsp, rn, imm); 1515361Srstrong@cs.ucsd.edu case 0x3: 1525361Srstrong@cs.ucsd.edu return new AndXImmCc(machInst, rdzr, rn, imm); 1535361Srstrong@cs.ucsd.edu } 1545361Srstrong@cs.ucsd.edu } 1555361Srstrong@cs.ucsd.edu case 0x5: 1565361Srstrong@cs.ucsd.edu { 1575361Srstrong@cs.ucsd.edu IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1585361Srstrong@cs.ucsd.edu IntRegIndex rdzr = makeZero(rd); 1595361Srstrong@cs.ucsd.edu uint32_t imm16 = bits(machInst, 20, 5); 1605353Svilas.sridharan@gmail.com uint32_t hw = bits(machInst, 22, 21); 1615353Svilas.sridharan@gmail.com switch (opc) { 1625353Svilas.sridharan@gmail.com case 0x0: 1633514Sktlim@umich.edu return new Movn(machInst, rdzr, imm16, hw * 16); 1643481Shsul@eecs.umich.edu case 0x1: 1656107Ssteve.reinhardt@amd.com return new Unknown64(machInst); 1666107Ssteve.reinhardt@amd.com case 0x2: 1673395Shsul@eecs.umich.edu return new Movz(machInst, rdzr, imm16, hw * 16); 1683514Sktlim@umich.edu case 0x3: 1693514Sktlim@umich.edu return new Movk(machInst, rdzr, imm16, hw * 16); 1703395Shsul@eecs.umich.edu } 1713478Shsul@eecs.umich.edu } 1723395Shsul@eecs.umich.edu case 0x6: 1735361Srstrong@cs.ucsd.edu if ((sf != n) || (!sf && (bits(immr, 5) || bits(imms, 5)))) 1745369Ssaidi@eecs.umich.edu return new Unknown64(machInst); 1755361Srstrong@cs.ucsd.edu switch (opc) { 1765361Srstrong@cs.ucsd.edu case 0x0: 1775361Srstrong@cs.ucsd.edu return new Sbfm64(machInst, rdzr, rn, immr, imms); 1785361Srstrong@cs.ucsd.edu case 0x1: 1795361Srstrong@cs.ucsd.edu return new Bfm64(machInst, rdzr, rn, immr, imms); 1805378Ssaidi@eecs.umich.edu case 0x2: 1816654Snate@binkert.org return new Ubfm64(machInst, rdzr, rn, immr, imms); 1825369Ssaidi@eecs.umich.edu case 0x3: 1835361Srstrong@cs.ucsd.edu return new Unknown64(machInst); 1845361Srstrong@cs.ucsd.edu } 1855361Srstrong@cs.ucsd.edu case 0x7: 1865361Srstrong@cs.ucsd.edu { 1875361Srstrong@cs.ucsd.edu IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1885361Srstrong@cs.ucsd.edu if (opc || bits(machInst, 21)) 1895361Srstrong@cs.ucsd.edu return new Unknown64(machInst); 1905361Srstrong@cs.ucsd.edu else 1915361Srstrong@cs.ucsd.edu return new Extr64(machInst, rdzr, rn, rm, imms); 1925361Srstrong@cs.ucsd.edu } 1937525Ssteve.reinhardt@amd.com } 1943395Shsul@eecs.umich.edu return new FailUnimplemented("Unhandled Case8", machInst); 1955369Ssaidi@eecs.umich.edu } 1965361Srstrong@cs.ucsd.edu} 1973395Shsul@eecs.umich.edu}}; 1983395Shsul@eecs.umich.edu 1993395Shsul@eecs.umich.eduoutput decoder {{ 2003395Shsul@eecs.umich.edunamespace Aarch64 2016654Snate@binkert.org{ 2023395Shsul@eecs.umich.edu StaticInstPtr 2037530Ssteve.reinhardt@amd.com decodeBranchExcSys(ExtMachInst machInst) 2047530Ssteve.reinhardt@amd.com { 2057530Ssteve.reinhardt@amd.com switch (bits(machInst, 30, 29)) { 2067530Ssteve.reinhardt@amd.com case 0x0: 2077530Ssteve.reinhardt@amd.com { 2087530Ssteve.reinhardt@amd.com int64_t imm = sext<26>(bits(machInst, 25, 0)) << 2; 2097530Ssteve.reinhardt@amd.com if (bits(machInst, 31) == 0) 2107530Ssteve.reinhardt@amd.com return new B64(machInst, imm); 2117530Ssteve.reinhardt@amd.com else 2127530Ssteve.reinhardt@amd.com return new Bl64(machInst, imm); 2135361Srstrong@cs.ucsd.edu } 2146654Snate@binkert.org case 0x1: 2153395Shsul@eecs.umich.edu { 2165361Srstrong@cs.ucsd.edu IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 2177525Ssteve.reinhardt@amd.com if (bits(machInst, 25) == 0) { 2185361Srstrong@cs.ucsd.edu int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2; 2195361Srstrong@cs.ucsd.edu if (bits(machInst, 24) == 0) 2205361Srstrong@cs.ucsd.edu return new Cbz64(machInst, imm, rt); 2215361Srstrong@cs.ucsd.edu else 2225361Srstrong@cs.ucsd.edu return new Cbnz64(machInst, imm, rt); 2235361Srstrong@cs.ucsd.edu } else { 2245361Srstrong@cs.ucsd.edu uint64_t bitmask = 0x1; 2255361Srstrong@cs.ucsd.edu bitmask <<= bits(machInst, 23, 19); 2265361Srstrong@cs.ucsd.edu int64_t imm = sext<14>(bits(machInst, 18, 5)) << 2; 2273999Ssaidi@eecs.umich.edu if (bits(machInst, 31)) 2285361Srstrong@cs.ucsd.edu bitmask <<= 32; 2295361Srstrong@cs.ucsd.edu if (bits(machInst, 24) == 0) 2305361Srstrong@cs.ucsd.edu return new Tbz64(machInst, bitmask, imm, rt); 2315361Srstrong@cs.ucsd.edu else 2325361Srstrong@cs.ucsd.edu return new Tbnz64(machInst, bitmask, imm, rt); 2336654Snate@binkert.org } 2345361Srstrong@cs.ucsd.edu } 2355361Srstrong@cs.ucsd.edu case 0x2: 2365361Srstrong@cs.ucsd.edu // bit 30:26=10101 2375361Srstrong@cs.ucsd.edu if (bits(machInst, 31) == 0) { 2385361Srstrong@cs.ucsd.edu if (bits(machInst, 25, 24) || bits(machInst, 4)) 2397525Ssteve.reinhardt@amd.com return new Unknown64(machInst); 2407525Ssteve.reinhardt@amd.com int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2; 2413395Shsul@eecs.umich.edu ConditionCode condCode = 2423481Shsul@eecs.umich.edu (ConditionCode)(uint8_t)(bits(machInst, 3, 0)); 2435361Srstrong@cs.ucsd.edu return new BCond64(machInst, imm, condCode); 2445361Srstrong@cs.ucsd.edu } else if (bits(machInst, 25, 24) == 0x0) { 2455361Srstrong@cs.ucsd.edu if (bits(machInst, 4, 2)) 2465361Srstrong@cs.ucsd.edu return new Unknown64(machInst); 2475361Srstrong@cs.ucsd.edu uint8_t decVal = (bits(machInst, 1, 0) << 0) | 2485361Srstrong@cs.ucsd.edu (bits(machInst, 23, 21) << 2); 2495361Srstrong@cs.ucsd.edu switch (decVal) { 2505361Srstrong@cs.ucsd.edu case 0x01: 2515361Srstrong@cs.ucsd.edu return new Svc64(machInst); 2525361Srstrong@cs.ucsd.edu case 0x02: 2535361Srstrong@cs.ucsd.edu return new Hvc64(machInst); 2545361Srstrong@cs.ucsd.edu case 0x03: 2553395Shsul@eecs.umich.edu return new Smc64(machInst); 2565361Srstrong@cs.ucsd.edu case 0x04: 2575361Srstrong@cs.ucsd.edu return new Brk64(machInst); 2585361Srstrong@cs.ucsd.edu case 0x08: 2595361Srstrong@cs.ucsd.edu return new FailUnimplemented("hlt", machInst); 2605361Srstrong@cs.ucsd.edu case 0x15: 2613395Shsul@eecs.umich.edu return new FailUnimplemented("dcps1", machInst); 2623395Shsul@eecs.umich.edu case 0x16: 2633395Shsul@eecs.umich.edu return new FailUnimplemented("dcps2", machInst); 2643395Shsul@eecs.umich.edu case 0x17: 2653395Shsul@eecs.umich.edu return new FailUnimplemented("dcps3", machInst); 2663481Shsul@eecs.umich.edu default: 2675361Srstrong@cs.ucsd.edu return new Unknown64(machInst); 2685361Srstrong@cs.ucsd.edu } 2695361Srstrong@cs.ucsd.edu } else if (bits(machInst, 25, 22) == 0x4) { 2705361Srstrong@cs.ucsd.edu // bit 31:22=1101010100 2715361Srstrong@cs.ucsd.edu bool l = bits(machInst, 21); 2725361Srstrong@cs.ucsd.edu uint8_t op0 = bits(machInst, 20, 19); 2735361Srstrong@cs.ucsd.edu uint8_t op1 = bits(machInst, 18, 16); 2745353Svilas.sridharan@gmail.com uint8_t crn = bits(machInst, 15, 12); 2755361Srstrong@cs.ucsd.edu uint8_t crm = bits(machInst, 11, 8); 2765361Srstrong@cs.ucsd.edu uint8_t op2 = bits(machInst, 7, 5); 2775361Srstrong@cs.ucsd.edu IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 2785072Ssaidi@eecs.umich.edu switch (op0) { 2793481Shsul@eecs.umich.edu case 0x0: 2805072Ssaidi@eecs.umich.edu if (rt != 0x1f || l) 2813395Shsul@eecs.umich.edu return new Unknown64(machInst); 2823395Shsul@eecs.umich.edu if (crn == 0x2 && op1 == 0x3) { 2833395Shsul@eecs.umich.edu switch (op2) { 2843395Shsul@eecs.umich.edu case 0x0: 2857489Ssteve.reinhardt@amd.com return new NopInst(machInst); 2867489Ssteve.reinhardt@amd.com case 0x1: 2877489Ssteve.reinhardt@amd.com return new YieldInst(machInst); 2887489Ssteve.reinhardt@amd.com case 0x2: 2897489Ssteve.reinhardt@amd.com return new WfeInst(machInst); 2907489Ssteve.reinhardt@amd.com case 0x3: 2917489Ssteve.reinhardt@amd.com return new WfiInst(machInst); 2927489Ssteve.reinhardt@amd.com case 0x4: 2937489Ssteve.reinhardt@amd.com return new SevInst(machInst); 2947489Ssteve.reinhardt@amd.com case 0x5: 2955361Srstrong@cs.ucsd.edu return new SevlInst(machInst); 2965361Srstrong@cs.ucsd.edu default: 2975361Srstrong@cs.ucsd.edu return new Unknown64(machInst); 2985361Srstrong@cs.ucsd.edu } 2995369Ssaidi@eecs.umich.edu } else if (crn == 0x3 && op1 == 0x3) { 3005361Srstrong@cs.ucsd.edu switch (op2) { 3015369Ssaidi@eecs.umich.edu case 0x2: 3023395Shsul@eecs.umich.edu return new Clrex64(machInst); 3035361Srstrong@cs.ucsd.edu case 0x4: 3045369Ssaidi@eecs.umich.edu return new Dsb64(machInst); 3055361Srstrong@cs.ucsd.edu case 0x5: 3063395Shsul@eecs.umich.edu return new Dmb64(machInst); 3075361Srstrong@cs.ucsd.edu case 0x6: 3085361Srstrong@cs.ucsd.edu return new Isb64(machInst); 3095361Srstrong@cs.ucsd.edu default: 3103395Shsul@eecs.umich.edu return new Unknown64(machInst); 3115361Srstrong@cs.ucsd.edu } 3125361Srstrong@cs.ucsd.edu } else if (crn == 0x4) { 3135361Srstrong@cs.ucsd.edu // MSR immediate 3143999Ssaidi@eecs.umich.edu switch (op1 << 3 | op2) { 3155361Srstrong@cs.ucsd.edu case 0x5: 3165361Srstrong@cs.ucsd.edu // SP 3177525Ssteve.reinhardt@amd.com return new MsrSP64(machInst, 3185361Srstrong@cs.ucsd.edu (IntRegIndex) MISCREG_SPSEL, 3195361Srstrong@cs.ucsd.edu INTREG_ZERO, 3205361Srstrong@cs.ucsd.edu crm & 0x1); 3213999Ssaidi@eecs.umich.edu case 0x1e: 3225361Srstrong@cs.ucsd.edu // DAIFSet 3235361Srstrong@cs.ucsd.edu return new MsrDAIFSet64( 3245361Srstrong@cs.ucsd.edu machInst, 3255369Ssaidi@eecs.umich.edu (IntRegIndex) MISCREG_DAIF, 3265369Ssaidi@eecs.umich.edu INTREG_ZERO, 3275369Ssaidi@eecs.umich.edu crm); 3285369Ssaidi@eecs.umich.edu case 0x1f: 3295361Srstrong@cs.ucsd.edu // DAIFClr 3305361Srstrong@cs.ucsd.edu return new MsrDAIFClr64( 3315361Srstrong@cs.ucsd.edu machInst, 3325361Srstrong@cs.ucsd.edu (IntRegIndex) MISCREG_DAIF, 3335361Srstrong@cs.ucsd.edu INTREG_ZERO, 3347525Ssteve.reinhardt@amd.com crm); 3355361Srstrong@cs.ucsd.edu default: 3365361Srstrong@cs.ucsd.edu return new Unknown64(machInst); 3375361Srstrong@cs.ucsd.edu } 3385361Srstrong@cs.ucsd.edu } else { 3395361Srstrong@cs.ucsd.edu return new Unknown64(machInst); 3405361Srstrong@cs.ucsd.edu } 3415361Srstrong@cs.ucsd.edu break; 3425361Srstrong@cs.ucsd.edu case 0x1: 3435361Srstrong@cs.ucsd.edu case 0x2: 3445361Srstrong@cs.ucsd.edu case 0x3: 3455361Srstrong@cs.ucsd.edu { 3465361Srstrong@cs.ucsd.edu // bit 31:22=1101010100, 20:19=11 3475361Srstrong@cs.ucsd.edu bool read = l; 3485361Srstrong@cs.ucsd.edu MiscRegIndex miscReg = 3495361Srstrong@cs.ucsd.edu decodeAArch64SysReg(op0, op1, crn, crm, op2); 3505361Srstrong@cs.ucsd.edu if (read) { 3517525Ssteve.reinhardt@amd.com if ((miscReg == MISCREG_DC_CIVAC_Xt) || 3525361Srstrong@cs.ucsd.edu (miscReg == MISCREG_DC_CVAC_Xt) || 3535361Srstrong@cs.ucsd.edu (miscReg == MISCREG_DC_IVAC_Xt) || 3545361Srstrong@cs.ucsd.edu (miscReg == MISCREG_DC_ZVA_Xt)) { 3555361Srstrong@cs.ucsd.edu return new Unknown64(machInst); 3565361Srstrong@cs.ucsd.edu } 3575361Srstrong@cs.ucsd.edu } 3585361Srstrong@cs.ucsd.edu // Check for invalid registers 3595361Srstrong@cs.ucsd.edu if (miscReg == MISCREG_UNKNOWN) { 3605361Srstrong@cs.ucsd.edu return new Unknown64(machInst); 3613395Shsul@eecs.umich.edu } else if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) { 3623395Shsul@eecs.umich.edu if (miscReg == MISCREG_NZCV) { 3633395Shsul@eecs.umich.edu if (read) 3647525Ssteve.reinhardt@amd.com return new MrsNZCV64(machInst, rt, (IntRegIndex) miscReg); 3653395Shsul@eecs.umich.edu else 3663395Shsul@eecs.umich.edu return new MsrNZCV64(machInst, (IntRegIndex) miscReg, rt); 3675361Srstrong@cs.ucsd.edu } 3683395Shsul@eecs.umich.edu uint32_t iss = msrMrs64IssBuild(read, op0, op1, crn, crm, op2, rt); 3693395Shsul@eecs.umich.edu if (read) { 3703511Shsul@eecs.umich.edu StaticInstPtr si = new Mrs64(machInst, rt, miscReg, iss); 3713395Shsul@eecs.umich.edu if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE]) 3723395Shsul@eecs.umich.edu si->setFlag(StaticInst::IsUnverifiable); 3733395Shsul@eecs.umich.edu return si; 3743395Shsul@eecs.umich.edu } else { 3753514Sktlim@umich.edu switch (miscReg) { 3763395Shsul@eecs.umich.edu case MISCREG_DC_ZVA_Xt: 3776776SBrad.Beckmann@amd.com return new Dczva(machInst, rt, miscReg, iss); 3787525Ssteve.reinhardt@amd.com case MISCREG_DC_CVAU_Xt: 3796776SBrad.Beckmann@amd.com return new Dccvau(machInst, rt, miscReg, iss); 380 case MISCREG_DC_CVAC_Xt: 381 return new Dccvac(machInst, rt, miscReg, iss); 382 case MISCREG_DC_CIVAC_Xt: 383 return new Dccivac(machInst, rt, miscReg, iss); 384 case MISCREG_DC_IVAC_Xt: 385 return new Dcivac(machInst, rt, miscReg, iss); 386 default: 387 return new Msr64(machInst, miscReg, rt, iss); 388 } 389 } 390 } else if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) { 391 std::string full_mnem = csprintf("%s %s", 392 read ? "mrs" : "msr", miscRegName[miscReg]); 393 return new WarnUnimplemented(read ? "mrs" : "msr", 394 machInst, full_mnem); 395 } else { 396 return new FailUnimplemented(read ? "mrs" : "msr", 397 machInst, 398 csprintf("%s %s", 399 read ? "mrs" : "msr", 400 miscRegName[miscReg])); 401 } 402 } 403 break; 404 } 405 } else if (bits(machInst, 25) == 0x1) { 406 uint8_t opc = bits(machInst, 24, 21); 407 uint8_t op2 = bits(machInst, 20, 16); 408 uint8_t op3 = bits(machInst, 15, 10); 409 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 410 uint8_t op4 = bits(machInst, 4, 0); 411 if (op2 != 0x1f || op3 != 0x0 || op4 != 0x0) 412 return new Unknown64(machInst); 413 switch (opc) { 414 case 0x0: 415 return new Br64(machInst, rn); 416 case 0x1: 417 return new Blr64(machInst, rn); 418 case 0x2: 419 return new Ret64(machInst, rn); 420 case 0x4: 421 if (rn != 0x1f) 422 return new Unknown64(machInst); 423 return new Eret64(machInst); 424 case 0x5: 425 if (rn != 0x1f) 426 return new Unknown64(machInst); 427 return new FailUnimplemented("dret", machInst); 428 } 429 } 430 default: 431 return new Unknown64(machInst); 432 } 433 return new FailUnimplemented("Unhandled Case7", machInst); 434 } 435} 436}}; 437 438output decoder {{ 439namespace Aarch64 440{ 441 StaticInstPtr 442 decodeLoadsStores(ExtMachInst machInst) 443 { 444 // bit 27,25=10 445 switch (bits(machInst, 29, 28)) { 446 case 0x0: 447 if (bits(machInst, 26) == 0) { 448 if (bits(machInst, 24) != 0) 449 return new Unknown64(machInst); 450 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 451 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 452 IntRegIndex rnsp = makeSP(rn); 453 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 454 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 455 uint8_t opc = (bits(machInst, 15) << 0) | 456 (bits(machInst, 23, 21) << 1); 457 uint8_t size = bits(machInst, 31, 30); 458 switch (opc) { 459 case 0x0: 460 switch (size) { 461 case 0x0: 462 return new STXRB64(machInst, rt, rnsp, rs); 463 case 0x1: 464 return new STXRH64(machInst, rt, rnsp, rs); 465 case 0x2: 466 return new STXRW64(machInst, rt, rnsp, rs); 467 case 0x3: 468 return new STXRX64(machInst, rt, rnsp, rs); 469 } 470 case 0x1: 471 switch (size) { 472 case 0x0: 473 return new STLXRB64(machInst, rt, rnsp, rs); 474 case 0x1: 475 return new STLXRH64(machInst, rt, rnsp, rs); 476 case 0x2: 477 return new STLXRW64(machInst, rt, rnsp, rs); 478 case 0x3: 479 return new STLXRX64(machInst, rt, rnsp, rs); 480 } 481 case 0x2: 482 switch (size) { 483 case 0x0: 484 case 0x1: 485 return new Unknown64(machInst); 486 case 0x2: 487 return new STXPW64(machInst, rs, rt, rt2, rnsp); 488 case 0x3: 489 return new STXPX64(machInst, rs, rt, rt2, rnsp); 490 } 491 492 case 0x3: 493 switch (size) { 494 case 0x0: 495 case 0x1: 496 return new Unknown64(machInst); 497 case 0x2: 498 return new STLXPW64(machInst, rs, rt, rt2, rnsp); 499 case 0x3: 500 return new STLXPX64(machInst, rs, rt, rt2, rnsp); 501 } 502 503 case 0x4: 504 switch (size) { 505 case 0x0: 506 return new LDXRB64(machInst, rt, rnsp, rs); 507 case 0x1: 508 return new LDXRH64(machInst, rt, rnsp, rs); 509 case 0x2: 510 return new LDXRW64(machInst, rt, rnsp, rs); 511 case 0x3: 512 return new LDXRX64(machInst, rt, rnsp, rs); 513 } 514 case 0x5: 515 switch (size) { 516 case 0x0: 517 return new LDAXRB64(machInst, rt, rnsp, rs); 518 case 0x1: 519 return new LDAXRH64(machInst, rt, rnsp, rs); 520 case 0x2: 521 return new LDAXRW64(machInst, rt, rnsp, rs); 522 case 0x3: 523 return new LDAXRX64(machInst, rt, rnsp, rs); 524 } 525 case 0x6: 526 switch (size) { 527 case 0x0: 528 case 0x1: 529 return new Unknown64(machInst); 530 case 0x2: 531 return new LDXPW64(machInst, rt, rt2, rnsp); 532 case 0x3: 533 return new LDXPX64(machInst, rt, rt2, rnsp); 534 } 535 536 case 0x7: 537 switch (size) { 538 case 0x0: 539 case 0x1: 540 return new Unknown64(machInst); 541 case 0x2: 542 return new LDAXPW64(machInst, rt, rt2, rnsp); 543 case 0x3: 544 return new LDAXPX64(machInst, rt, rt2, rnsp); 545 } 546 547 case 0x9: 548 switch (size) { 549 case 0x0: 550 return new STLRB64(machInst, rt, rnsp); 551 case 0x1: 552 return new STLRH64(machInst, rt, rnsp); 553 case 0x2: 554 return new STLRW64(machInst, rt, rnsp); 555 case 0x3: 556 return new STLRX64(machInst, rt, rnsp); 557 } 558 case 0xd: 559 switch (size) { 560 case 0x0: 561 return new LDARB64(machInst, rt, rnsp); 562 case 0x1: 563 return new LDARH64(machInst, rt, rnsp); 564 case 0x2: 565 return new LDARW64(machInst, rt, rnsp); 566 case 0x3: 567 return new LDARX64(machInst, rt, rnsp); 568 } 569 default: 570 return new Unknown64(machInst); 571 } 572 } else if (bits(machInst, 31)) { 573 return new Unknown64(machInst); 574 } else { 575 return decodeNeonMem(machInst); 576 } 577 case 0x1: 578 { 579 if (bits(machInst, 24) != 0) 580 return new Unknown64(machInst); 581 uint8_t switchVal = (bits(machInst, 26) << 0) | 582 (bits(machInst, 31, 30) << 1); 583 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2; 584 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 585 switch (switchVal) { 586 case 0x0: 587 return new LDRWL64_LIT(machInst, rt, imm); 588 case 0x1: 589 return new LDRSFP64_LIT(machInst, rt, imm); 590 case 0x2: 591 return new LDRXL64_LIT(machInst, rt, imm); 592 case 0x3: 593 return new LDRDFP64_LIT(machInst, rt, imm); 594 case 0x4: 595 return new LDRSWL64_LIT(machInst, rt, imm); 596 case 0x5: 597 return new BigFpMemLit("ldr", machInst, rt, imm); 598 case 0x6: 599 return new PRFM64_LIT(machInst, rt, imm); 600 default: 601 return new Unknown64(machInst); 602 } 603 } 604 case 0x2: 605 { 606 uint8_t opc = bits(machInst, 31, 30); 607 if (opc >= 3) 608 return new Unknown64(machInst); 609 uint32_t size = 0; 610 bool fp = bits(machInst, 26); 611 bool load = bits(machInst, 22); 612 if (fp) { 613 size = 4 << opc; 614 } else { 615 if ((opc == 1) && !load) 616 return new Unknown64(machInst); 617 size = (opc == 0 || opc == 1) ? 4 : 8; 618 } 619 uint8_t type = bits(machInst, 24, 23); 620 int64_t imm = sext<7>(bits(machInst, 21, 15)) * size; 621 622 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 623 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 624 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 625 626 bool noAlloc = (type == 0); 627 bool signExt = !noAlloc && !fp && opc == 1; 628 PairMemOp::AddrMode mode; 629 const char *mnemonic = NULL; 630 switch (type) { 631 case 0x0: 632 case 0x2: 633 mode = PairMemOp::AddrMd_Offset; 634 break; 635 case 0x1: 636 mode = PairMemOp::AddrMd_PostIndex; 637 break; 638 case 0x3: 639 mode = PairMemOp::AddrMd_PreIndex; 640 break; 641 default: 642 return new Unknown64(machInst); 643 } 644 if (load) { 645 if (noAlloc) 646 mnemonic = "ldnp"; 647 else if (signExt) 648 mnemonic = "ldpsw"; 649 else 650 mnemonic = "ldp"; 651 } else { 652 if (noAlloc) 653 mnemonic = "stnp"; 654 else 655 mnemonic = "stp"; 656 } 657 658 return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc, 659 signExt, false, false, imm, mode, rn, rt, rt2); 660 } 661 // bit 29:27=111, 25=0 662 case 0x3: 663 { 664 uint8_t switchVal = (bits(machInst, 23, 22) << 0) | 665 (bits(machInst, 26) << 2) | 666 (bits(machInst, 31, 30) << 3); 667 if (bits(machInst, 24) == 1) { 668 uint64_t imm12 = bits(machInst, 21, 10); 669 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 670 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 671 IntRegIndex rnsp = makeSP(rn); 672 switch (switchVal) { 673 case 0x00: 674 return new STRB64_IMM(machInst, rt, rnsp, imm12); 675 case 0x01: 676 return new LDRB64_IMM(machInst, rt, rnsp, imm12); 677 case 0x02: 678 return new LDRSBX64_IMM(machInst, rt, rnsp, imm12); 679 case 0x03: 680 return new LDRSBW64_IMM(machInst, rt, rnsp, imm12); 681 case 0x04: 682 return new STRBFP64_IMM(machInst, rt, rnsp, imm12); 683 case 0x05: 684 return new LDRBFP64_IMM(machInst, rt, rnsp, imm12); 685 case 0x06: 686 return new BigFpMemImm("str", machInst, false, 687 rt, rnsp, imm12 << 4); 688 case 0x07: 689 return new BigFpMemImm("ldr", machInst, true, 690 rt, rnsp, imm12 << 4); 691 case 0x08: 692 return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1); 693 case 0x09: 694 return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1); 695 case 0x0a: 696 return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1); 697 case 0x0b: 698 return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1); 699 case 0x0c: 700 return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 701 case 0x0d: 702 return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 703 case 0x10: 704 return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2); 705 case 0x11: 706 return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2); 707 case 0x12: 708 return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2); 709 case 0x14: 710 return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 711 case 0x15: 712 return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 713 case 0x18: 714 return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3); 715 case 0x19: 716 return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3); 717 case 0x1a: 718 return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3); 719 case 0x1c: 720 return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 721 case 0x1d: 722 return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 723 default: 724 return new Unknown64(machInst); 725 } 726 } else if (bits(machInst, 21) == 1) { 727 if (bits(machInst, 11, 10) != 0x2) 728 return new Unknown64(machInst); 729 if (!bits(machInst, 14)) 730 return new Unknown64(machInst); 731 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 732 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 733 IntRegIndex rnsp = makeSP(rn); 734 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 735 ArmExtendType type = 736 (ArmExtendType)(uint32_t)bits(machInst, 15, 13); 737 uint8_t s = bits(machInst, 12); 738 switch (switchVal) { 739 case 0x00: 740 return new STRB64_REG(machInst, rt, rnsp, rm, type, 0); 741 case 0x01: 742 return new LDRB64_REG(machInst, rt, rnsp, rm, type, 0); 743 case 0x02: 744 return new LDRSBX64_REG(machInst, rt, rnsp, rm, type, 0); 745 case 0x03: 746 return new LDRSBW64_REG(machInst, rt, rnsp, rm, type, 0); 747 case 0x04: 748 return new STRBFP64_REG(machInst, rt, rnsp, rm, type, 0); 749 case 0x05: 750 return new LDRBFP64_REG(machInst, rt, rnsp, rm, type, 0); 751 case 0x6: 752 return new BigFpMemReg("str", machInst, false, 753 rt, rnsp, rm, type, s * 4); 754 case 0x7: 755 return new BigFpMemReg("ldr", machInst, true, 756 rt, rnsp, rm, type, s * 4); 757 case 0x08: 758 return new STRH64_REG(machInst, rt, rnsp, rm, type, s); 759 case 0x09: 760 return new LDRH64_REG(machInst, rt, rnsp, rm, type, s); 761 case 0x0a: 762 return new LDRSHX64_REG(machInst, rt, rnsp, rm, type, s); 763 case 0x0b: 764 return new LDRSHW64_REG(machInst, rt, rnsp, rm, type, s); 765 case 0x0c: 766 return new STRHFP64_REG(machInst, rt, rnsp, rm, type, s); 767 case 0x0d: 768 return new LDRHFP64_REG(machInst, rt, rnsp, rm, type, s); 769 case 0x10: 770 return new STRW64_REG(machInst, rt, rnsp, rm, type, s * 2); 771 case 0x11: 772 return new LDRW64_REG(machInst, rt, rnsp, rm, type, s * 2); 773 case 0x12: 774 return new LDRSW64_REG(machInst, rt, rnsp, rm, type, s * 2); 775 case 0x14: 776 return new STRSFP64_REG(machInst, rt, rnsp, rm, type, s * 2); 777 case 0x15: 778 return new LDRSFP64_REG(machInst, rt, rnsp, rm, type, s * 2); 779 case 0x18: 780 return new STRX64_REG(machInst, rt, rnsp, rm, type, s * 3); 781 case 0x19: 782 return new LDRX64_REG(machInst, rt, rnsp, rm, type, s * 3); 783 case 0x1a: 784 return new PRFM64_REG(machInst, rt, rnsp, rm, type, s * 3); 785 case 0x1c: 786 return new STRDFP64_REG(machInst, rt, rnsp, rm, type, s * 3); 787 case 0x1d: 788 return new LDRDFP64_REG(machInst, rt, rnsp, rm, type, s * 3); 789 default: 790 return new Unknown64(machInst); 791 } 792 } else { 793 // bit 29:27=111, 25:24=00, 21=0 794 switch (bits(machInst, 11, 10)) { 795 case 0x0: 796 { 797 IntRegIndex rt = 798 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 799 IntRegIndex rn = 800 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 801 IntRegIndex rnsp = makeSP(rn); 802 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 803 switch (switchVal) { 804 case 0x00: 805 return new STURB64_IMM(machInst, rt, rnsp, imm); 806 case 0x01: 807 return new LDURB64_IMM(machInst, rt, rnsp, imm); 808 case 0x02: 809 return new LDURSBX64_IMM(machInst, rt, rnsp, imm); 810 case 0x03: 811 return new LDURSBW64_IMM(machInst, rt, rnsp, imm); 812 case 0x04: 813 return new STURBFP64_IMM(machInst, rt, rnsp, imm); 814 case 0x05: 815 return new LDURBFP64_IMM(machInst, rt, rnsp, imm); 816 case 0x06: 817 return new BigFpMemImm("stur", machInst, false, 818 rt, rnsp, imm); 819 case 0x07: 820 return new BigFpMemImm("ldur", machInst, true, 821 rt, rnsp, imm); 822 case 0x08: 823 return new STURH64_IMM(machInst, rt, rnsp, imm); 824 case 0x09: 825 return new LDURH64_IMM(machInst, rt, rnsp, imm); 826 case 0x0a: 827 return new LDURSHX64_IMM(machInst, rt, rnsp, imm); 828 case 0x0b: 829 return new LDURSHW64_IMM(machInst, rt, rnsp, imm); 830 case 0x0c: 831 return new STURHFP64_IMM(machInst, rt, rnsp, imm); 832 case 0x0d: 833 return new LDURHFP64_IMM(machInst, rt, rnsp, imm); 834 case 0x10: 835 return new STURW64_IMM(machInst, rt, rnsp, imm); 836 case 0x11: 837 return new LDURW64_IMM(machInst, rt, rnsp, imm); 838 case 0x12: 839 return new LDURSW64_IMM(machInst, rt, rnsp, imm); 840 case 0x14: 841 return new STURSFP64_IMM(machInst, rt, rnsp, imm); 842 case 0x15: 843 return new LDURSFP64_IMM(machInst, rt, rnsp, imm); 844 case 0x18: 845 return new STURX64_IMM(machInst, rt, rnsp, imm); 846 case 0x19: 847 return new LDURX64_IMM(machInst, rt, rnsp, imm); 848 case 0x1a: 849 return new PRFUM64_IMM(machInst, rt, rnsp, imm); 850 case 0x1c: 851 return new STURDFP64_IMM(machInst, rt, rnsp, imm); 852 case 0x1d: 853 return new LDURDFP64_IMM(machInst, rt, rnsp, imm); 854 default: 855 return new Unknown64(machInst); 856 } 857 } 858 // bit 29:27=111, 25:24=00, 21=0, 11:10=01 859 case 0x1: 860 { 861 IntRegIndex rt = 862 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 863 IntRegIndex rn = 864 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 865 IntRegIndex rnsp = makeSP(rn); 866 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 867 switch (switchVal) { 868 case 0x00: 869 return new STRB64_POST(machInst, rt, rnsp, imm); 870 case 0x01: 871 return new LDRB64_POST(machInst, rt, rnsp, imm); 872 case 0x02: 873 return new LDRSBX64_POST(machInst, rt, rnsp, imm); 874 case 0x03: 875 return new LDRSBW64_POST(machInst, rt, rnsp, imm); 876 case 0x04: 877 return new STRBFP64_POST(machInst, rt, rnsp, imm); 878 case 0x05: 879 return new LDRBFP64_POST(machInst, rt, rnsp, imm); 880 case 0x06: 881 return new BigFpMemPost("str", machInst, false, 882 rt, rnsp, imm); 883 case 0x07: 884 return new BigFpMemPost("ldr", machInst, true, 885 rt, rnsp, imm); 886 case 0x08: 887 return new STRH64_POST(machInst, rt, rnsp, imm); 888 case 0x09: 889 return new LDRH64_POST(machInst, rt, rnsp, imm); 890 case 0x0a: 891 return new LDRSHX64_POST(machInst, rt, rnsp, imm); 892 case 0x0b: 893 return new LDRSHW64_POST(machInst, rt, rnsp, imm); 894 case 0x0c: 895 return new STRHFP64_POST(machInst, rt, rnsp, imm); 896 case 0x0d: 897 return new LDRHFP64_POST(machInst, rt, rnsp, imm); 898 case 0x10: 899 return new STRW64_POST(machInst, rt, rnsp, imm); 900 case 0x11: 901 return new LDRW64_POST(machInst, rt, rnsp, imm); 902 case 0x12: 903 return new LDRSW64_POST(machInst, rt, rnsp, imm); 904 case 0x14: 905 return new STRSFP64_POST(machInst, rt, rnsp, imm); 906 case 0x15: 907 return new LDRSFP64_POST(machInst, rt, rnsp, imm); 908 case 0x18: 909 return new STRX64_POST(machInst, rt, rnsp, imm); 910 case 0x19: 911 return new LDRX64_POST(machInst, rt, rnsp, imm); 912 case 0x1c: 913 return new STRDFP64_POST(machInst, rt, rnsp, imm); 914 case 0x1d: 915 return new LDRDFP64_POST(machInst, rt, rnsp, imm); 916 default: 917 return new Unknown64(machInst); 918 } 919 } 920 case 0x2: 921 { 922 IntRegIndex rt = 923 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 924 IntRegIndex rn = 925 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 926 IntRegIndex rnsp = makeSP(rn); 927 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 928 switch (switchVal) { 929 case 0x00: 930 return new STTRB64_IMM(machInst, rt, rnsp, imm); 931 case 0x01: 932 return new LDTRB64_IMM(machInst, rt, rnsp, imm); 933 case 0x02: 934 return new LDTRSBX64_IMM(machInst, rt, rnsp, imm); 935 case 0x03: 936 return new LDTRSBW64_IMM(machInst, rt, rnsp, imm); 937 case 0x08: 938 return new STTRH64_IMM(machInst, rt, rnsp, imm); 939 case 0x09: 940 return new LDTRH64_IMM(machInst, rt, rnsp, imm); 941 case 0x0a: 942 return new LDTRSHX64_IMM(machInst, rt, rnsp, imm); 943 case 0x0b: 944 return new LDTRSHW64_IMM(machInst, rt, rnsp, imm); 945 case 0x10: 946 return new STTRW64_IMM(machInst, rt, rnsp, imm); 947 case 0x11: 948 return new LDTRW64_IMM(machInst, rt, rnsp, imm); 949 case 0x12: 950 return new LDTRSW64_IMM(machInst, rt, rnsp, imm); 951 case 0x18: 952 return new STTRX64_IMM(machInst, rt, rnsp, imm); 953 case 0x19: 954 return new LDTRX64_IMM(machInst, rt, rnsp, imm); 955 default: 956 return new Unknown64(machInst); 957 } 958 } 959 case 0x3: 960 { 961 IntRegIndex rt = 962 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 963 IntRegIndex rn = 964 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 965 IntRegIndex rnsp = makeSP(rn); 966 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 967 switch (switchVal) { 968 case 0x00: 969 return new STRB64_PRE(machInst, rt, rnsp, imm); 970 case 0x01: 971 return new LDRB64_PRE(machInst, rt, rnsp, imm); 972 case 0x02: 973 return new LDRSBX64_PRE(machInst, rt, rnsp, imm); 974 case 0x03: 975 return new LDRSBW64_PRE(machInst, rt, rnsp, imm); 976 case 0x04: 977 return new STRBFP64_PRE(machInst, rt, rnsp, imm); 978 case 0x05: 979 return new LDRBFP64_PRE(machInst, rt, rnsp, imm); 980 case 0x06: 981 return new BigFpMemPre("str", machInst, false, 982 rt, rnsp, imm); 983 case 0x07: 984 return new BigFpMemPre("ldr", machInst, true, 985 rt, rnsp, imm); 986 case 0x08: 987 return new STRH64_PRE(machInst, rt, rnsp, imm); 988 case 0x09: 989 return new LDRH64_PRE(machInst, rt, rnsp, imm); 990 case 0x0a: 991 return new LDRSHX64_PRE(machInst, rt, rnsp, imm); 992 case 0x0b: 993 return new LDRSHW64_PRE(machInst, rt, rnsp, imm); 994 case 0x0c: 995 return new STRHFP64_PRE(machInst, rt, rnsp, imm); 996 case 0x0d: 997 return new LDRHFP64_PRE(machInst, rt, rnsp, imm); 998 case 0x10: 999 return new STRW64_PRE(machInst, rt, rnsp, imm); 1000 case 0x11: 1001 return new LDRW64_PRE(machInst, rt, rnsp, imm); 1002 case 0x12: 1003 return new LDRSW64_PRE(machInst, rt, rnsp, imm); 1004 case 0x14: 1005 return new STRSFP64_PRE(machInst, rt, rnsp, imm); 1006 case 0x15: 1007 return new LDRSFP64_PRE(machInst, rt, rnsp, imm); 1008 case 0x18: 1009 return new STRX64_PRE(machInst, rt, rnsp, imm); 1010 case 0x19: 1011 return new LDRX64_PRE(machInst, rt, rnsp, imm); 1012 case 0x1c: 1013 return new STRDFP64_PRE(machInst, rt, rnsp, imm); 1014 case 0x1d: 1015 return new LDRDFP64_PRE(machInst, rt, rnsp, imm); 1016 default: 1017 return new Unknown64(machInst); 1018 } 1019 } 1020 } 1021 } 1022 } 1023 } 1024 return new FailUnimplemented("Unhandled Case1", machInst); 1025 } 1026} 1027}}; 1028 1029output decoder {{ 1030namespace Aarch64 1031{ 1032 StaticInstPtr 1033 decodeDataProcReg(ExtMachInst machInst) 1034 { 1035 uint8_t switchVal = (bits(machInst, 28) << 1) | 1036 (bits(machInst, 24) << 0); 1037 switch (switchVal) { 1038 case 0x0: 1039 { 1040 uint8_t switchVal = (bits(machInst, 21) << 0) | 1041 (bits(machInst, 30, 29) << 1); 1042 ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1043 uint8_t imm6 = bits(machInst, 15, 10); 1044 bool sf = bits(machInst, 31); 1045 if (!sf && (imm6 & 0x20)) 1046 return new Unknown64(machInst); 1047 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1048 IntRegIndex rdzr = makeZero(rd); 1049 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1050 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1051 1052 switch (switchVal) { 1053 case 0x0: 1054 return new AndXSReg(machInst, rdzr, rn, rm, imm6, type); 1055 case 0x1: 1056 return new BicXSReg(machInst, rdzr, rn, rm, imm6, type); 1057 case 0x2: 1058 return new OrrXSReg(machInst, rdzr, rn, rm, imm6, type); 1059 case 0x3: 1060 return new OrnXSReg(machInst, rdzr, rn, rm, imm6, type); 1061 case 0x4: 1062 return new EorXSReg(machInst, rdzr, rn, rm, imm6, type); 1063 case 0x5: 1064 return new EonXSReg(machInst, rdzr, rn, rm, imm6, type); 1065 case 0x6: 1066 return new AndXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1067 case 0x7: 1068 return new BicXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1069 } 1070 } 1071 case 0x1: 1072 { 1073 uint8_t switchVal = bits(machInst, 30, 29); 1074 if (bits(machInst, 21) == 0) { 1075 ArmShiftType type = 1076 (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1077 if (type == ROR) 1078 return new Unknown64(machInst); 1079 uint8_t imm6 = bits(machInst, 15, 10); 1080 if (!bits(machInst, 31) && bits(imm6, 5)) 1081 return new Unknown64(machInst); 1082 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1083 IntRegIndex rdzr = makeZero(rd); 1084 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1085 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1086 switch (switchVal) { 1087 case 0x0: 1088 return new AddXSReg(machInst, rdzr, rn, rm, imm6, type); 1089 case 0x1: 1090 return new AddXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1091 case 0x2: 1092 return new SubXSReg(machInst, rdzr, rn, rm, imm6, type); 1093 case 0x3: 1094 return new SubXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1095 } 1096 } else { 1097 if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4) 1098 return new Unknown64(machInst); 1099 ArmExtendType type = 1100 (ArmExtendType)(uint8_t)bits(machInst, 15, 13); 1101 uint8_t imm3 = bits(machInst, 12, 10); 1102 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1103 IntRegIndex rdsp = makeSP(rd); 1104 IntRegIndex rdzr = makeZero(rd); 1105 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1106 IntRegIndex rnsp = makeSP(rn); 1107 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1108 1109 switch (switchVal) { 1110 case 0x0: 1111 return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1112 case 0x1: 1113 return new AddXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1114 case 0x2: 1115 return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1116 case 0x3: 1117 return new SubXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1118 } 1119 } 1120 } 1121 case 0x2: 1122 { 1123 if (bits(machInst, 21) == 1) 1124 return new Unknown64(machInst); 1125 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1126 IntRegIndex rdzr = makeZero(rd); 1127 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1128 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1129 switch (bits(machInst, 23, 22)) { 1130 case 0x0: 1131 { 1132 if (bits(machInst, 15, 10)) 1133 return new Unknown64(machInst); 1134 uint8_t switchVal = bits(machInst, 30, 29); 1135 switch (switchVal) { 1136 case 0x0: 1137 return new AdcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1138 case 0x1: 1139 return new AdcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1140 case 0x2: 1141 return new SbcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1142 case 0x3: 1143 return new SbcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1144 } 1145 } 1146 case 0x1: 1147 { 1148 if ((bits(machInst, 4) == 1) || 1149 (bits(machInst, 10) == 1) || 1150 (bits(machInst, 29) == 0)) { 1151 return new Unknown64(machInst); 1152 } 1153 ConditionCode cond = 1154 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1155 uint8_t flags = bits(machInst, 3, 0); 1156 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1157 if (bits(machInst, 11) == 0) { 1158 IntRegIndex rm = 1159 (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1160 if (bits(machInst, 30) == 0) { 1161 return new CcmnReg64(machInst, rn, rm, cond, flags); 1162 } else { 1163 return new CcmpReg64(machInst, rn, rm, cond, flags); 1164 } 1165 } else { 1166 uint8_t imm5 = bits(machInst, 20, 16); 1167 if (bits(machInst, 30) == 0) { 1168 return new CcmnImm64(machInst, rn, imm5, cond, flags); 1169 } else { 1170 return new CcmpImm64(machInst, rn, imm5, cond, flags); 1171 } 1172 } 1173 } 1174 case 0x2: 1175 { 1176 if (bits(machInst, 29) == 1 || 1177 bits(machInst, 11) == 1) { 1178 return new Unknown64(machInst); 1179 } 1180 uint8_t switchVal = (bits(machInst, 10) << 0) | 1181 (bits(machInst, 30) << 1); 1182 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1183 IntRegIndex rdzr = makeZero(rd); 1184 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1185 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1186 ConditionCode cond = 1187 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1188 switch (switchVal) { 1189 case 0x0: 1190 return new Csel64(machInst, rdzr, rn, rm, cond); 1191 case 0x1: 1192 return new Csinc64(machInst, rdzr, rn, rm, cond); 1193 case 0x2: 1194 return new Csinv64(machInst, rdzr, rn, rm, cond); 1195 case 0x3: 1196 return new Csneg64(machInst, rdzr, rn, rm, cond); 1197 } 1198 } 1199 case 0x3: 1200 if (bits(machInst, 30) == 0) { 1201 if (bits(machInst, 29) != 0) 1202 return new Unknown64(machInst); 1203 uint8_t switchVal = bits(machInst, 15, 10); 1204 switch (switchVal) { 1205 case 0x2: 1206 return new Udiv64(machInst, rdzr, rn, rm); 1207 case 0x3: 1208 return new Sdiv64(machInst, rdzr, rn, rm); 1209 case 0x8: 1210 return new Lslv64(machInst, rdzr, rn, rm); 1211 case 0x9: 1212 return new Lsrv64(machInst, rdzr, rn, rm); 1213 case 0xa: 1214 return new Asrv64(machInst, rdzr, rn, rm); 1215 case 0xb: 1216 return new Rorv64(machInst, rdzr, rn, rm); 1217 case 0x10: 1218 return new Crc32b64(machInst, rdzr, rn, rm); 1219 case 0x11: 1220 return new Crc32h64(machInst, rdzr, rn, rm); 1221 case 0x12: 1222 return new Crc32w64(machInst, rdzr, rn, rm); 1223 case 0x13: 1224 return new Crc32x64(machInst, rdzr, rn, rm); 1225 case 0x14: 1226 return new Crc32cb64(machInst, rdzr, rn, rm); 1227 case 0x15: 1228 return new Crc32ch64(machInst, rdzr, rn, rm); 1229 case 0x16: 1230 return new Crc32cw64(machInst, rdzr, rn, rm); 1231 case 0x17: 1232 return new Crc32cx64(machInst, rdzr, rn, rm); 1233 default: 1234 return new Unknown64(machInst); 1235 } 1236 } else { 1237 if (bits(machInst, 20, 16) != 0 || 1238 bits(machInst, 29) != 0) { 1239 return new Unknown64(machInst); 1240 } 1241 uint8_t switchVal = bits(machInst, 15, 10); 1242 switch (switchVal) { 1243 case 0x0: 1244 return new Rbit64(machInst, rdzr, rn); 1245 case 0x1: 1246 return new Rev1664(machInst, rdzr, rn); 1247 case 0x2: 1248 if (bits(machInst, 31) == 0) 1249 return new Rev64(machInst, rdzr, rn); 1250 else 1251 return new Rev3264(machInst, rdzr, rn); 1252 case 0x3: 1253 if (bits(machInst, 31) != 1) 1254 return new Unknown64(machInst); 1255 return new Rev64(machInst, rdzr, rn); 1256 case 0x4: 1257 return new Clz64(machInst, rdzr, rn); 1258 case 0x5: 1259 return new Cls64(machInst, rdzr, rn); 1260 } 1261 } 1262 } 1263 } 1264 case 0x3: 1265 { 1266 if (bits(machInst, 30, 29) != 0x0 || 1267 (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0)) 1268 return new Unknown64(machInst); 1269 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1270 IntRegIndex rdzr = makeZero(rd); 1271 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1272 IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 1273 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1274 switch (bits(machInst, 23, 21)) { 1275 case 0x0: 1276 if (bits(machInst, 15) == 0) 1277 return new Madd64(machInst, rdzr, ra, rn, rm); 1278 else 1279 return new Msub64(machInst, rdzr, ra, rn, rm); 1280 case 0x1: 1281 if (bits(machInst, 15) == 0) 1282 return new Smaddl64(machInst, rdzr, ra, rn, rm); 1283 else 1284 return new Smsubl64(machInst, rdzr, ra, rn, rm); 1285 case 0x2: 1286 if (bits(machInst, 15) != 0) 1287 return new Unknown64(machInst); 1288 return new Smulh64(machInst, rdzr, rn, rm); 1289 case 0x5: 1290 if (bits(machInst, 15) == 0) 1291 return new Umaddl64(machInst, rdzr, ra, rn, rm); 1292 else 1293 return new Umsubl64(machInst, rdzr, ra, rn, rm); 1294 case 0x6: 1295 if (bits(machInst, 15) != 0) 1296 return new Unknown64(machInst); 1297 return new Umulh64(machInst, rdzr, rn, rm); 1298 default: 1299 return new Unknown64(machInst); 1300 } 1301 } 1302 } 1303 return new FailUnimplemented("Unhandled Case2", machInst); 1304 } 1305} 1306}}; 1307 1308output decoder {{ 1309namespace Aarch64 1310{ 1311 template <typename DecoderFeatures> 1312 StaticInstPtr 1313 decodeAdvSIMD(ExtMachInst machInst) 1314 { 1315 if (bits(machInst, 24) == 1) { 1316 if (bits(machInst, 10) == 0) { 1317 return decodeNeonIndexedElem<DecoderFeatures>(machInst); 1318 } else if (bits(machInst, 23) == 1) { 1319 return new Unknown64(machInst); 1320 } else { 1321 if (bits(machInst, 22, 19)) { 1322 return decodeNeonShiftByImm(machInst); 1323 } else { 1324 return decodeNeonModImm(machInst); 1325 } 1326 } 1327 } else if (bits(machInst, 21) == 1) { 1328 if (bits(machInst, 10) == 1) { 1329 return decodeNeon3Same<DecoderFeatures>(machInst); 1330 } else if (bits(machInst, 11) == 0) { 1331 return decodeNeon3Diff(machInst); 1332 } else if (bits(machInst, 20, 17) == 0x0) { 1333 return decodeNeon2RegMisc(machInst); 1334 } else if (bits(machInst, 20, 17) == 0x8) { 1335 return decodeNeonAcrossLanes(machInst); 1336 } else { 1337 return new Unknown64(machInst); 1338 } 1339 } else if (bits(machInst, 24) || 1340 bits(machInst, 21) || 1341 bits(machInst, 15)) { 1342 return new Unknown64(machInst); 1343 } else if (bits(machInst, 10) == 1) { 1344 if (bits(machInst, 23, 22)) 1345 return new Unknown64(machInst); 1346 return decodeNeonCopy(machInst); 1347 } else if (bits(machInst, 29) == 1) { 1348 return decodeNeonExt(machInst); 1349 } else if (bits(machInst, 11) == 1) { 1350 return decodeNeonZipUzpTrn(machInst); 1351 } else if (bits(machInst, 23, 22) == 0x0) { 1352 return decodeNeonTblTbx(machInst); 1353 } else { 1354 return new Unknown64(machInst); 1355 } 1356 return new FailUnimplemented("Unhandled Case3", machInst); 1357 } 1358} 1359}}; 1360 1361 1362output decoder {{ 1363namespace Aarch64 1364{ 1365 StaticInstPtr 1366 // bit 30=0, 28:25=1111 1367 decodeFp(ExtMachInst machInst) 1368 { 1369 if (bits(machInst, 24) == 1) { 1370 if (bits(machInst, 31) || bits(machInst, 29)) 1371 return new Unknown64(machInst); 1372 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1373 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1374 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 1375 IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 14, 10); 1376 uint8_t switchVal = (bits(machInst, 23, 21) << 1) | 1377 (bits(machInst, 15) << 0); 1378 switch (switchVal) { 1379 case 0x0: // FMADD Sd = Sa + Sn*Sm 1380 return new FMAddS(machInst, rd, rn, rm, ra); 1381 case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm 1382 return new FMSubS(machInst, rd, rn, rm, ra); 1383 case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm 1384 return new FNMAddS(machInst, rd, rn, rm, ra); 1385 case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm 1386 return new FNMSubS(machInst, rd, rn, rm, ra); 1387 case 0x4: // FMADD Dd = Da + Dn*Dm 1388 return new FMAddD(machInst, rd, rn, rm, ra); 1389 case 0x5: // FMSUB Dd = Da + (-Dn)*Dm 1390 return new FMSubD(machInst, rd, rn, rm, ra); 1391 case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm 1392 return new FNMAddD(machInst, rd, rn, rm, ra); 1393 case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm 1394 return new FNMSubD(machInst, rd, rn, rm, ra); 1395 default: 1396 return new Unknown64(machInst); 1397 } 1398 } else if (bits(machInst, 21) == 0) { 1399 bool s = bits(machInst, 29); 1400 if (s) 1401 return new Unknown64(machInst); 1402 uint8_t switchVal = bits(machInst, 20, 16); 1403 uint8_t type = bits(machInst, 23, 22); 1404 uint8_t scale = bits(machInst, 15, 10); 1405 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1406 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1407 if (bits(machInst, 18, 17) == 3 && scale != 0) 1408 return new Unknown64(machInst); 1409 // 30:24=0011110, 21=0 1410 switch (switchVal) { 1411 case 0x00: 1412 return new FailUnimplemented("fcvtns", machInst); 1413 case 0x01: 1414 return new FailUnimplemented("fcvtnu", machInst); 1415 case 0x02: 1416 switch ( (bits(machInst, 31) << 2) | type ) { 1417 case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits)) 1418 return new FcvtSFixedFpSW(machInst, rd, rn, scale); 1419 case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits)) 1420 return new FcvtSFixedFpDW(machInst, rd, rn, scale); 1421 case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits)) 1422 return new FcvtSFixedFpSX(machInst, rd, rn, scale); 1423 case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits)) 1424 return new FcvtSFixedFpDX(machInst, rd, rn, scale); 1425 default: 1426 return new Unknown64(machInst); 1427 } 1428 case 0x03: 1429 switch ( (bits(machInst, 31) << 2) | type ) { 1430 case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits)) 1431 return new FcvtUFixedFpSW(machInst, rd, rn, scale); 1432 case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits)) 1433 return new FcvtUFixedFpDW(machInst, rd, rn, scale); 1434 case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits)) 1435 return new FcvtUFixedFpSX(machInst, rd, rn, scale); 1436 case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits)) 1437 return new FcvtUFixedFpDX(machInst, rd, rn, scale); 1438 default: 1439 return new Unknown64(machInst); 1440 } 1441 case 0x04: 1442 return new FailUnimplemented("fcvtas", machInst); 1443 case 0x05: 1444 return new FailUnimplemented("fcvtau", machInst); 1445 case 0x08: 1446 return new FailUnimplemented("fcvtps", machInst); 1447 case 0x09: 1448 return new FailUnimplemented("fcvtpu", machInst); 1449 case 0x0e: 1450 return new FailUnimplemented("fmov elem. to 64", machInst); 1451 case 0x0f: 1452 return new FailUnimplemented("fmov 64 bit", machInst); 1453 case 0x10: 1454 return new FailUnimplemented("fcvtms", machInst); 1455 case 0x11: 1456 return new FailUnimplemented("fcvtmu", machInst); 1457 case 0x18: 1458 switch ( (bits(machInst, 31) << 2) | type ) { 1459 case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 1460 return new FcvtFpSFixedSW(machInst, rd, rn, scale); 1461 case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 1462 return new FcvtFpSFixedDW(machInst, rd, rn, scale); 1463 case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 1464 return new FcvtFpSFixedSX(machInst, rd, rn, scale); 1465 case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 1466 return new FcvtFpSFixedDX(machInst, rd, rn, scale); 1467 default: 1468 return new Unknown64(machInst); 1469 } 1470 case 0x19: 1471 switch ( (bits(machInst, 31) << 2) | type ) { 1472 case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 1473 return new FcvtFpUFixedSW(machInst, rd, rn, scale); 1474 case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 1475 return new FcvtFpUFixedDW(machInst, rd, rn, scale); 1476 case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 1477 return new FcvtFpUFixedSX(machInst, rd, rn, scale); 1478 case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 1479 return new FcvtFpUFixedDX(machInst, rd, rn, scale); 1480 default: 1481 return new Unknown64(machInst); 1482 } 1483 } 1484 } else { 1485 // 30=0, 28:24=11110, 21=1 1486 uint8_t type = bits(machInst, 23, 22); 1487 uint8_t imm8 = bits(machInst, 20, 13); 1488 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1489 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1490 switch (bits(machInst, 11, 10)) { 1491 case 0x0: 1492 if (bits(machInst, 12) == 1) { 1493 if (bits(machInst, 31) || 1494 bits(machInst, 29) || 1495 bits(machInst, 9, 5)) { 1496 return new Unknown64(machInst); 1497 } 1498 // 31:29=000, 28:24=11110, 21=1, 12:10=100 1499 if (type == 0) { 1500 // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5) 1501 // :imm8<5:0>:Zeros(19) 1502 uint32_t imm = vfp_modified_imm(imm8, false); 1503 return new FmovImmS(machInst, rd, imm); 1504 } else if (type == 1) { 1505 // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8) 1506 // :imm8<5:0>:Zeros(48) 1507 uint64_t imm = vfp_modified_imm(imm8, true); 1508 return new FmovImmD(machInst, rd, imm); 1509 } else { 1510 return new Unknown64(machInst); 1511 } 1512 } else if (bits(machInst, 13) == 1) { 1513 if (bits(machInst, 31) || 1514 bits(machInst, 29) || 1515 bits(machInst, 15, 14) || 1516 bits(machInst, 23) || 1517 bits(machInst, 2, 0)) { 1518 return new Unknown64(machInst); 1519 } 1520 uint8_t switchVal = (bits(machInst, 4, 3) << 0) | 1521 (bits(machInst, 22) << 2); 1522 IntRegIndex rm = (IntRegIndex)(uint32_t) 1523 bits(machInst, 20, 16); 1524 // 28:23=000111100, 21=1, 15:10=001000, 2:0=000 1525 switch (switchVal) { 1526 case 0x0: 1527 // FCMP flags = compareQuiet(Sn,Sm) 1528 return new FCmpRegS(machInst, rn, rm); 1529 case 0x1: 1530 // FCMP flags = compareQuiet(Sn,0.0) 1531 return new FCmpImmS(machInst, rn, 0); 1532 case 0x2: 1533 // FCMPE flags = compareSignaling(Sn,Sm) 1534 return new FCmpERegS(machInst, rn, rm); 1535 case 0x3: 1536 // FCMPE flags = compareSignaling(Sn,0.0) 1537 return new FCmpEImmS(machInst, rn, 0); 1538 case 0x4: 1539 // FCMP flags = compareQuiet(Dn,Dm) 1540 return new FCmpRegD(machInst, rn, rm); 1541 case 0x5: 1542 // FCMP flags = compareQuiet(Dn,0.0) 1543 return new FCmpImmD(machInst, rn, 0); 1544 case 0x6: 1545 // FCMPE flags = compareSignaling(Dn,Dm) 1546 return new FCmpERegD(machInst, rn, rm); 1547 case 0x7: 1548 // FCMPE flags = compareSignaling(Dn,0.0) 1549 return new FCmpEImmD(machInst, rn, 0); 1550 default: 1551 return new Unknown64(machInst); 1552 } 1553 } else if (bits(machInst, 14) == 1) { 1554 if (bits(machInst, 31) || bits(machInst, 29)) 1555 return new Unknown64(machInst); 1556 uint8_t opcode = bits(machInst, 20, 15); 1557 // Bits 31:24=00011110, 21=1, 14:10=10000 1558 switch (opcode) { 1559 case 0x0: 1560 if (type == 0) 1561 // FMOV Sd = Sn 1562 return new FmovRegS(machInst, rd, rn); 1563 else if (type == 1) 1564 // FMOV Dd = Dn 1565 return new FmovRegD(machInst, rd, rn); 1566 break; 1567 case 0x1: 1568 if (type == 0) 1569 // FABS Sd = abs(Sn) 1570 return new FAbsS(machInst, rd, rn); 1571 else if (type == 1) 1572 // FABS Dd = abs(Dn) 1573 return new FAbsD(machInst, rd, rn); 1574 break; 1575 case 0x2: 1576 if (type == 0) 1577 // FNEG Sd = -Sn 1578 return new FNegS(machInst, rd, rn); 1579 else if (type == 1) 1580 // FNEG Dd = -Dn 1581 return new FNegD(machInst, rd, rn); 1582 break; 1583 case 0x3: 1584 if (type == 0) 1585 // FSQRT Sd = sqrt(Sn) 1586 return new FSqrtS(machInst, rd, rn); 1587 else if (type == 1) 1588 // FSQRT Dd = sqrt(Dn) 1589 return new FSqrtD(machInst, rd, rn); 1590 break; 1591 case 0x4: 1592 if (type == 1) 1593 // FCVT Sd = convertFormat(Dn) 1594 return new FcvtFpDFpS(machInst, rd, rn); 1595 else if (type == 3) 1596 // FCVT Sd = convertFormat(Hn) 1597 return new FcvtFpHFpS(machInst, rd, rn); 1598 break; 1599 case 0x5: 1600 if (type == 0) 1601 // FCVT Dd = convertFormat(Sn) 1602 return new FCvtFpSFpD(machInst, rd, rn); 1603 else if (type == 3) 1604 // FCVT Dd = convertFormat(Hn) 1605 return new FcvtFpHFpD(machInst, rd, rn); 1606 break; 1607 case 0x7: 1608 if (type == 0) 1609 // FCVT Hd = convertFormat(Sn) 1610 return new FcvtFpSFpH(machInst, rd, rn); 1611 else if (type == 1) 1612 // FCVT Hd = convertFormat(Dn) 1613 return new FcvtFpDFpH(machInst, rd, rn); 1614 break; 1615 case 0x8: 1616 if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn) 1617 return new FRIntNS(machInst, rd, rn); 1618 else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn) 1619 return new FRIntND(machInst, rd, rn); 1620 break; 1621 case 0x9: 1622 if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn) 1623 return new FRIntPS(machInst, rd, rn); 1624 else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn) 1625 return new FRIntPD(machInst, rd, rn); 1626 break; 1627 case 0xa: 1628 if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn) 1629 return new FRIntMS(machInst, rd, rn); 1630 else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn) 1631 return new FRIntMD(machInst, rd, rn); 1632 break; 1633 case 0xb: 1634 if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn) 1635 return new FRIntZS(machInst, rd, rn); 1636 else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn) 1637 return new FRIntZD(machInst, rd, rn); 1638 break; 1639 case 0xc: 1640 if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn) 1641 return new FRIntAS(machInst, rd, rn); 1642 else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn) 1643 return new FRIntAD(machInst, rd, rn); 1644 break; 1645 case 0xe: 1646 if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn) 1647 return new FRIntXS(machInst, rd, rn); 1648 else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn) 1649 return new FRIntXD(machInst, rd, rn); 1650 break; 1651 case 0xf: 1652 if (type == 0) // FRINTI Sd = roundToIntegral(Sn) 1653 return new FRIntIS(machInst, rd, rn); 1654 else if (type == 1) // FRINTI Dd = roundToIntegral(Dn) 1655 return new FRIntID(machInst, rd, rn); 1656 break; 1657 default: 1658 return new Unknown64(machInst); 1659 } 1660 return new Unknown64(machInst); 1661 } else if (bits(machInst, 15) == 1) { 1662 return new Unknown64(machInst); 1663 } else { 1664 if (bits(machInst, 29)) 1665 return new Unknown64(machInst); 1666 uint8_t rmode = bits(machInst, 20, 19); 1667 uint8_t switchVal1 = bits(machInst, 18, 16); 1668 uint8_t switchVal2 = (type << 1) | bits(machInst, 31); 1669 // 30:24=0011110, 21=1, 15:10=000000 1670 switch (switchVal1) { 1671 case 0x0: 1672 switch ((switchVal2 << 2) | rmode) { 1673 case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn) 1674 return new FcvtFpSIntWSN(machInst, rd, rn); 1675 case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn) 1676 return new FcvtFpSIntWSP(machInst, rd, rn); 1677 case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn) 1678 return new FcvtFpSIntWSM(machInst, rd, rn); 1679 case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn) 1680 return new FcvtFpSIntWSZ(machInst, rd, rn); 1681 case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn) 1682 return new FcvtFpSIntXSN(machInst, rd, rn); 1683 case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn) 1684 return new FcvtFpSIntXSP(machInst, rd, rn); 1685 case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn) 1686 return new FcvtFpSIntXSM(machInst, rd, rn); 1687 case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn) 1688 return new FcvtFpSIntXSZ(machInst, rd, rn); 1689 case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn) 1690 return new FcvtFpSIntWDN(machInst, rd, rn); 1691 case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn) 1692 return new FcvtFpSIntWDP(machInst, rd, rn); 1693 case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn) 1694 return new FcvtFpSIntWDM(machInst, rd, rn); 1695 case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn) 1696 return new FcvtFpSIntWDZ(machInst, rd, rn); 1697 case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn) 1698 return new FcvtFpSIntXDN(machInst, rd, rn); 1699 case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn) 1700 return new FcvtFpSIntXDP(machInst, rd, rn); 1701 case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn) 1702 return new FcvtFpSIntXDM(machInst, rd, rn); 1703 case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn) 1704 return new FcvtFpSIntXDZ(machInst, rd, rn); 1705 default: 1706 return new Unknown64(machInst); 1707 } 1708 case 0x1: 1709 switch ((switchVal2 << 2) | rmode) { 1710 case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn) 1711 return new FcvtFpUIntWSN(machInst, rd, rn); 1712 case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn) 1713 return new FcvtFpUIntWSP(machInst, rd, rn); 1714 case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn) 1715 return new FcvtFpUIntWSM(machInst, rd, rn); 1716 case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn) 1717 return new FcvtFpUIntWSZ(machInst, rd, rn); 1718 case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn) 1719 return new FcvtFpUIntXSN(machInst, rd, rn); 1720 case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn) 1721 return new FcvtFpUIntXSP(machInst, rd, rn); 1722 case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn) 1723 return new FcvtFpUIntXSM(machInst, rd, rn); 1724 case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn) 1725 return new FcvtFpUIntXSZ(machInst, rd, rn); 1726 case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn) 1727 return new FcvtFpUIntWDN(machInst, rd, rn); 1728 case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn) 1729 return new FcvtFpUIntWDP(machInst, rd, rn); 1730 case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn) 1731 return new FcvtFpUIntWDM(machInst, rd, rn); 1732 case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn) 1733 return new FcvtFpUIntWDZ(machInst, rd, rn); 1734 case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn) 1735 return new FcvtFpUIntXDN(machInst, rd, rn); 1736 case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn) 1737 return new FcvtFpUIntXDP(machInst, rd, rn); 1738 case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn) 1739 return new FcvtFpUIntXDM(machInst, rd, rn); 1740 case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn) 1741 return new FcvtFpUIntXDZ(machInst, rd, rn); 1742 default: 1743 return new Unknown64(machInst); 1744 } 1745 case 0x2: 1746 if (rmode != 0) 1747 return new Unknown64(machInst); 1748 switch (switchVal2) { 1749 case 0: // SCVTF Sd = convertFromInt(Wn) 1750 return new FcvtWSIntFpS(machInst, rd, rn); 1751 case 1: // SCVTF Sd = convertFromInt(Xn) 1752 return new FcvtXSIntFpS(machInst, rd, rn); 1753 case 2: // SCVTF Dd = convertFromInt(Wn) 1754 return new FcvtWSIntFpD(machInst, rd, rn); 1755 case 3: // SCVTF Dd = convertFromInt(Xn) 1756 return new FcvtXSIntFpD(machInst, rd, rn); 1757 default: 1758 return new Unknown64(machInst); 1759 } 1760 case 0x3: 1761 switch (switchVal2) { 1762 case 0: // UCVTF Sd = convertFromInt(Wn) 1763 return new FcvtWUIntFpS(machInst, rd, rn); 1764 case 1: // UCVTF Sd = convertFromInt(Xn) 1765 return new FcvtXUIntFpS(machInst, rd, rn); 1766 case 2: // UCVTF Dd = convertFromInt(Wn) 1767 return new FcvtWUIntFpD(machInst, rd, rn); 1768 case 3: // UCVTF Dd = convertFromInt(Xn) 1769 return new FcvtXUIntFpD(machInst, rd, rn); 1770 default: 1771 return new Unknown64(machInst); 1772 } 1773 case 0x4: 1774 if (rmode != 0) 1775 return new Unknown64(machInst); 1776 switch (switchVal2) { 1777 case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn) 1778 return new FcvtFpSIntWSA(machInst, rd, rn); 1779 case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn) 1780 return new FcvtFpSIntXSA(machInst, rd, rn); 1781 case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 1782 return new FcvtFpSIntWDA(machInst, rd, rn); 1783 case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 1784 return new FcvtFpSIntXDA(machInst, rd, rn); 1785 default: 1786 return new Unknown64(machInst); 1787 } 1788 case 0x5: 1789 switch (switchVal2) { 1790 case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn) 1791 return new FcvtFpUIntWSA(machInst, rd, rn); 1792 case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn) 1793 return new FcvtFpUIntXSA(machInst, rd, rn); 1794 case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn) 1795 return new FcvtFpUIntWDA(machInst, rd, rn); 1796 case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn) 1797 return new FcvtFpUIntXDA(machInst, rd, rn); 1798 default: 1799 return new Unknown64(machInst); 1800 } 1801 case 0x06: 1802 switch (switchVal2) { 1803 case 0: // FMOV Wd = Sn 1804 if (rmode != 0) 1805 return new Unknown64(machInst); 1806 return new FmovRegCoreW(machInst, rd, rn); 1807 case 3: // FMOV Xd = Dn 1808 if (rmode != 0) 1809 return new Unknown64(machInst); 1810 return new FmovRegCoreX(machInst, rd, rn); 1811 case 5: // FMOV Xd = Vn<127:64> 1812 if (rmode != 1) 1813 return new Unknown64(machInst); 1814 return new FmovURegCoreX(machInst, rd, rn); 1815 default: 1816 return new Unknown64(machInst); 1817 } 1818 break; 1819 case 0x07: 1820 switch (switchVal2) { 1821 case 0: // FMOV Sd = Wn 1822 if (rmode != 0) 1823 return new Unknown64(machInst); 1824 return new FmovCoreRegW(machInst, rd, rn); 1825 case 3: // FMOV Xd = Dn 1826 if (rmode != 0) 1827 return new Unknown64(machInst); 1828 return new FmovCoreRegX(machInst, rd, rn); 1829 case 5: // FMOV Xd = Vn<127:64> 1830 if (rmode != 1) 1831 return new Unknown64(machInst); 1832 return new FmovUCoreRegX(machInst, rd, rn); 1833 default: 1834 return new Unknown64(machInst); 1835 } 1836 break; 1837 default: // Warning! missing cases in switch statement above, that still need to be added 1838 return new Unknown64(machInst); 1839 } 1840 } 1841 case 0x1: 1842 { 1843 if (bits(machInst, 31) || 1844 bits(machInst, 29) || 1845 bits(machInst, 23)) { 1846 return new Unknown64(machInst); 1847 } 1848 IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16); 1849 IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5); 1850 uint8_t imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0); 1851 ConditionCode cond = 1852 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 1853 uint8_t switchVal = (bits(machInst, 4) << 0) | 1854 (bits(machInst, 22) << 1); 1855 // 31:23=000111100, 21=1, 11:10=01 1856 switch (switchVal) { 1857 case 0x0: 1858 // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv 1859 return new FCCmpRegS(machInst, rn, rm, cond, imm); 1860 case 0x1: 1861 // FCCMP flags = if cond then compareSignaling(Sn,Sm) 1862 // else #nzcv 1863 return new FCCmpERegS(machInst, rn, rm, cond, imm); 1864 case 0x2: 1865 // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv 1866 return new FCCmpRegD(machInst, rn, rm, cond, imm); 1867 case 0x3: 1868 // FCCMP flags = if cond then compareSignaling(Dn,Dm) 1869 // else #nzcv 1870 return new FCCmpERegD(machInst, rn, rm, cond, imm); 1871 default: 1872 return new Unknown64(machInst); 1873 } 1874 } 1875 case 0x2: 1876 { 1877 if (bits(machInst, 31) || 1878 bits(machInst, 29) || 1879 bits(machInst, 23)) { 1880 return new Unknown64(machInst); 1881 } 1882 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1883 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1884 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 1885 uint8_t switchVal = (bits(machInst, 15, 12) << 0) | 1886 (bits(machInst, 22) << 4); 1887 switch (switchVal) { 1888 case 0x00: // FMUL Sd = Sn * Sm 1889 return new FMulS(machInst, rd, rn, rm); 1890 case 0x10: // FMUL Dd = Dn * Dm 1891 return new FMulD(machInst, rd, rn, rm); 1892 case 0x01: // FDIV Sd = Sn / Sm 1893 return new FDivS(machInst, rd, rn, rm); 1894 case 0x11: // FDIV Dd = Dn / Dm 1895 return new FDivD(machInst, rd, rn, rm); 1896 case 0x02: // FADD Sd = Sn + Sm 1897 return new FAddS(machInst, rd, rn, rm); 1898 case 0x12: // FADD Dd = Dn + Dm 1899 return new FAddD(machInst, rd, rn, rm); 1900 case 0x03: // FSUB Sd = Sn - Sm 1901 return new FSubS(machInst, rd, rn, rm); 1902 case 0x13: // FSUB Dd = Dn - Dm 1903 return new FSubD(machInst, rd, rn, rm); 1904 case 0x04: // FMAX Sd = max(Sn, Sm) 1905 return new FMaxS(machInst, rd, rn, rm); 1906 case 0x14: // FMAX Dd = max(Dn, Dm) 1907 return new FMaxD(machInst, rd, rn, rm); 1908 case 0x05: // FMIN Sd = min(Sn, Sm) 1909 return new FMinS(machInst, rd, rn, rm); 1910 case 0x15: // FMIN Dd = min(Dn, Dm) 1911 return new FMinD(machInst, rd, rn, rm); 1912 case 0x06: // FMAXNM Sd = maxNum(Sn, Sm) 1913 return new FMaxNMS(machInst, rd, rn, rm); 1914 case 0x16: // FMAXNM Dd = maxNum(Dn, Dm) 1915 return new FMaxNMD(machInst, rd, rn, rm); 1916 case 0x07: // FMINNM Sd = minNum(Sn, Sm) 1917 return new FMinNMS(machInst, rd, rn, rm); 1918 case 0x17: // FMINNM Dd = minNum(Dn, Dm) 1919 return new FMinNMD(machInst, rd, rn, rm); 1920 case 0x08: // FNMUL Sd = -(Sn * Sm) 1921 return new FNMulS(machInst, rd, rn, rm); 1922 case 0x18: // FNMUL Dd = -(Dn * Dm) 1923 return new FNMulD(machInst, rd, rn, rm); 1924 default: 1925 return new Unknown64(machInst); 1926 } 1927 } 1928 case 0x3: 1929 { 1930 if (bits(machInst, 31) || bits(machInst, 29)) 1931 return new Unknown64(machInst); 1932 uint8_t type = bits(machInst, 23, 22); 1933 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1934 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1935 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 1936 ConditionCode cond = 1937 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 1938 if (type == 0) // FCSEL Sd = if cond then Sn else Sm 1939 return new FCSelS(machInst, rd, rn, rm, cond); 1940 else if (type == 1) // FCSEL Dd = if cond then Dn else Dm 1941 return new FCSelD(machInst, rd, rn, rm, cond); 1942 else 1943 return new Unknown64(machInst); 1944 } 1945 } 1946 } 1947 return new FailUnimplemented("Unhandled Case4", machInst); 1948 } 1949} 1950}}; 1951 1952output decoder {{ 1953namespace Aarch64 1954{ 1955 StaticInstPtr 1956 decodeAdvSIMDScalar(ExtMachInst machInst) 1957 { 1958 if (bits(machInst, 24) == 1) { 1959 if (bits(machInst, 10) == 0) { 1960 return decodeNeonScIndexedElem(machInst); 1961 } else if (bits(machInst, 23) == 0) { 1962 return decodeNeonScShiftByImm(machInst); 1963 } 1964 } else if (bits(machInst, 21) == 1) { 1965 if (bits(machInst, 10) == 1) { 1966 return decodeNeonSc3Same(machInst); 1967 } else if (bits(machInst, 11) == 0) { 1968 return decodeNeonSc3Diff(machInst); 1969 } else if (bits(machInst, 20, 17) == 0x0) { 1970 return decodeNeonSc2RegMisc(machInst); 1971 } else if (bits(machInst, 20, 17) == 0x8) { 1972 return decodeNeonScPwise(machInst); 1973 } else { 1974 return new Unknown64(machInst); 1975 } 1976 } else if (bits(machInst, 23, 22) == 0 && 1977 bits(machInst, 15) == 0 && 1978 bits(machInst, 10) == 1) { 1979 return decodeNeonScCopy(machInst); 1980 } else { 1981 return new Unknown64(machInst); 1982 } 1983 return new FailUnimplemented("Unhandled Case6", machInst); 1984 } 1985} 1986}}; 1987 1988output decoder {{ 1989namespace Aarch64 1990{ 1991 template <typename DecoderFeatures> 1992 StaticInstPtr 1993 decodeFpAdvSIMD(ExtMachInst machInst) 1994 { 1995 1996 if (bits(machInst, 28) == 0) { 1997 if (bits(machInst, 31) == 0) { 1998 return decodeAdvSIMD<DecoderFeatures>(machInst); 1999 } else { 2000 return new Unknown64(machInst); 2001 } 2002 } else if (bits(machInst, 30) == 0) { 2003 return decodeFp(machInst); 2004 } else if (bits(machInst, 31) == 0) { 2005 return decodeAdvSIMDScalar(machInst); 2006 } else { 2007 return new Unknown64(machInst); 2008 } 2009 } 2010} 2011}}; 2012 2013let {{ 2014 decoder_output =''' 2015namespace Aarch64 2016{''' 2017 for decoderFlavour, type_dict in decoders.iteritems(): 2018 decoder_output +=''' 2019template StaticInstPtr decodeFpAdvSIMD<%(df)sDecoder>(ExtMachInst machInst); 2020''' % { "df" : decoderFlavour } 2021 decoder_output +=''' 2022}''' 2023}}; 2024 2025output decoder {{ 2026namespace Aarch64 2027{ 2028 StaticInstPtr 2029 decodeGem5Ops(ExtMachInst machInst) 2030 { 2031 const uint32_t m5func = bits(machInst, 23, 16); 2032 switch (m5func) { 2033 case M5OP_ARM: return new Arm(machInst); 2034 case M5OP_QUIESCE: return new Quiesce(machInst); 2035 case M5OP_QUIESCE_NS: return new QuiesceNs64(machInst); 2036 case M5OP_QUIESCE_CYCLE: return new QuiesceCycles64(machInst); 2037 case M5OP_QUIESCE_TIME: return new QuiesceTime64(machInst); 2038 case M5OP_RPNS: return new Rpns64(machInst); 2039 case M5OP_WAKE_CPU: return new WakeCPU64(machInst); 2040 case M5OP_DEPRECATED1: return new Deprecated_ivlb(machInst); 2041 case M5OP_DEPRECATED2: return new Deprecated_ivle(machInst); 2042 case M5OP_DEPRECATED3: return new Deprecated_exit (machInst); 2043 case M5OP_EXIT: return new M5exit64(machInst); 2044 case M5OP_FAIL: return new M5fail64(machInst); 2045 case M5OP_LOAD_SYMBOL: return new Loadsymbol(machInst); 2046 case M5OP_INIT_PARAM: return new Initparam64(machInst); 2047 case M5OP_RESET_STATS: return new Resetstats64(machInst); 2048 case M5OP_DUMP_STATS: return new Dumpstats64(machInst); 2049 case M5OP_DUMP_RESET_STATS: return new Dumpresetstats64(machInst); 2050 case M5OP_CHECKPOINT: return new M5checkpoint64(machInst); 2051 case M5OP_WRITE_FILE: return new M5writefile64(machInst); 2052 case M5OP_READ_FILE: return new M5readfile64(machInst); 2053 case M5OP_DEBUG_BREAK: return new M5break(machInst); 2054 case M5OP_SWITCH_CPU: return new M5switchcpu(machInst); 2055 case M5OP_ADD_SYMBOL: return new M5addsymbol64(machInst); 2056 case M5OP_PANIC: return new M5panic(machInst); 2057 case M5OP_WORK_BEGIN: return new M5workbegin64(machInst); 2058 case M5OP_WORK_END: return new M5workend64(machInst); 2059 default: return new Unknown64(machInst); 2060 } 2061 } 2062} 2063}}; 2064 2065def format Aarch64() {{ 2066 decode_block = ''' 2067 { 2068 using namespace Aarch64; 2069 if (bits(machInst, 27) == 0x0) { 2070 if (bits(machInst, 28) == 0x0) 2071 return new Unknown64(machInst); 2072 else if (bits(machInst, 26) == 0) 2073 // bit 28:26=100 2074 return decodeDataProcImm(machInst); 2075 else 2076 // bit 28:26=101 2077 return decodeBranchExcSys(machInst); 2078 } else if (bits(machInst, 25) == 0) { 2079 // bit 27=1, 25=0 2080 return decodeLoadsStores(machInst); 2081 } else if (bits(machInst, 26) == 0) { 2082 // bit 27:25=101 2083 return decodeDataProcReg(machInst); 2084 } else if (bits(machInst, 24) == 1 && 2085 bits(machInst, 31, 28) == 0xF) { 2086 return decodeGem5Ops(machInst); 2087 } else { 2088 // bit 27:25=111 2089 switch(decoderFlavour){ 2090 default: 2091 return decodeFpAdvSIMD<GenericDecoder>(machInst); 2092 } 2093 } 2094 } 2095 ''' 2096}}; 2097