fp.isa revision 12595
17322Sgblack@eecs.umich.edu// -*- mode:c++ -*- 27322Sgblack@eecs.umich.edu 37322Sgblack@eecs.umich.edu// Copyright (c) 2010-2011,2016 ARM Limited 47322Sgblack@eecs.umich.edu// All rights reserved 57322Sgblack@eecs.umich.edu// 67322Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall 77322Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual 87322Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating 97322Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software 107322Sgblack@eecs.umich.edu// licensed hereunder. You may use the software subject to the license 117322Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated 127322Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software, 137322Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form. 147322Sgblack@eecs.umich.edu// 157322Sgblack@eecs.umich.edu// Copyright (c) 2007-2008 The Florida State University 167322Sgblack@eecs.umich.edu// All rights reserved. 177322Sgblack@eecs.umich.edu// 187322Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 197322Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 207322Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 217322Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 227322Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 237322Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 247322Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 257322Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 267322Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 277322Sgblack@eecs.umich.edu// this software without specific prior written permission. 287322Sgblack@eecs.umich.edu// 297322Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 307322Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 317322Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 327322Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 337322Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 347322Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 357322Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 367322Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 377322Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 387322Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 397322Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 407376Sgblack@eecs.umich.edu// 417376Sgblack@eecs.umich.edu// Authors: Stephen Hines 427376Sgblack@eecs.umich.edu 437376Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////// 447376Sgblack@eecs.umich.edu// 457376Sgblack@eecs.umich.edu// Floating Point operate instructions 467376Sgblack@eecs.umich.edu// 477376Sgblack@eecs.umich.edu 487376Sgblack@eecs.umich.eduoutput header {{ 497376Sgblack@eecs.umich.edu 507376Sgblack@eecs.umich.edu template<template <typename T> class Base> 517376Sgblack@eecs.umich.edu StaticInstPtr 527376Sgblack@eecs.umich.edu newNeonMemInst(const unsigned size, 537376Sgblack@eecs.umich.edu const ExtMachInst &machInst, 547376Sgblack@eecs.umich.edu const RegIndex dest, const RegIndex ra, 557376Sgblack@eecs.umich.edu const uint32_t imm, const unsigned extraMemFlags) 567376Sgblack@eecs.umich.edu { 577376Sgblack@eecs.umich.edu switch (size) { 587376Sgblack@eecs.umich.edu case 0: 597376Sgblack@eecs.umich.edu return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags); 607376Sgblack@eecs.umich.edu case 1: 617376Sgblack@eecs.umich.edu return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags); 627376Sgblack@eecs.umich.edu case 2: 637376Sgblack@eecs.umich.edu return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags); 647376Sgblack@eecs.umich.edu case 3: 657376Sgblack@eecs.umich.edu return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags); 667376Sgblack@eecs.umich.edu default: 677376Sgblack@eecs.umich.edu panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 687376Sgblack@eecs.umich.edu } 697376Sgblack@eecs.umich.edu } 707376Sgblack@eecs.umich.edu 717376Sgblack@eecs.umich.edu template<template <typename T> class Base> 727376Sgblack@eecs.umich.edu StaticInstPtr 737376Sgblack@eecs.umich.edu newNeonMixInst(const unsigned size, 747376Sgblack@eecs.umich.edu const ExtMachInst &machInst, 757376Sgblack@eecs.umich.edu const RegIndex dest, const RegIndex op1, 767376Sgblack@eecs.umich.edu const uint32_t step) 777376Sgblack@eecs.umich.edu { 787376Sgblack@eecs.umich.edu switch (size) { 797376Sgblack@eecs.umich.edu case 0: 807376Sgblack@eecs.umich.edu return new Base<uint8_t>(machInst, dest, op1, step); 817376Sgblack@eecs.umich.edu case 1: 827376Sgblack@eecs.umich.edu return new Base<uint16_t>(machInst, dest, op1, step); 837376Sgblack@eecs.umich.edu case 2: 847376Sgblack@eecs.umich.edu return new Base<uint32_t>(machInst, dest, op1, step); 857376Sgblack@eecs.umich.edu case 3: 867376Sgblack@eecs.umich.edu return new Base<uint64_t>(machInst, dest, op1, step); 877376Sgblack@eecs.umich.edu default: 887376Sgblack@eecs.umich.edu panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 897376Sgblack@eecs.umich.edu } 907376Sgblack@eecs.umich.edu } 917376Sgblack@eecs.umich.edu 927376Sgblack@eecs.umich.edu}}; 937376Sgblack@eecs.umich.edu 947376Sgblack@eecs.umich.edulet {{ 957376Sgblack@eecs.umich.edu header_output = ''' 967376Sgblack@eecs.umich.edu StaticInstPtr 977376Sgblack@eecs.umich.edu decodeNeonMem(ExtMachInst machInst); 987376Sgblack@eecs.umich.edu 997376Sgblack@eecs.umich.edu StaticInstPtr 1007376Sgblack@eecs.umich.edu decodeNeonData(ExtMachInst machInst); 1017376Sgblack@eecs.umich.edu ''' 1027376Sgblack@eecs.umich.edu 1037376Sgblack@eecs.umich.edu decoder_output = ''' 1047376Sgblack@eecs.umich.edu StaticInstPtr 1057376Sgblack@eecs.umich.edu decodeNeonMem(ExtMachInst machInst) 1067376Sgblack@eecs.umich.edu { 1077376Sgblack@eecs.umich.edu const uint32_t b = bits(machInst, 11, 8); 1087376Sgblack@eecs.umich.edu const bool single = bits(machInst, 23); 1097376Sgblack@eecs.umich.edu const bool singleAll = single && (bits(b, 3, 2) == 3); 1107376Sgblack@eecs.umich.edu const bool load = bits(machInst, 21); 1117376Sgblack@eecs.umich.edu 1127376Sgblack@eecs.umich.edu unsigned width = 0; 1137376Sgblack@eecs.umich.edu 1147376Sgblack@eecs.umich.edu if (single) { 1157376Sgblack@eecs.umich.edu width = bits(b, 1, 0) + 1; 1167376Sgblack@eecs.umich.edu } else { 1177376Sgblack@eecs.umich.edu switch (bits(b, 3, 1)) { 1187376Sgblack@eecs.umich.edu case 0x0: width = 4; 1197376Sgblack@eecs.umich.edu break; 1207376Sgblack@eecs.umich.edu case 0x1: width = (b & 0x1) ? 2 : 1; 1217376Sgblack@eecs.umich.edu break; 1227376Sgblack@eecs.umich.edu case 0x2: width = 3; 1237376Sgblack@eecs.umich.edu break; 1247376Sgblack@eecs.umich.edu case 0x3: width = 1; 1257376Sgblack@eecs.umich.edu break; 1267376Sgblack@eecs.umich.edu case 0x4: width = 2; 1277376Sgblack@eecs.umich.edu break; 1287376Sgblack@eecs.umich.edu case 0x5: 1297376Sgblack@eecs.umich.edu if ((b & 0x1) == 0) { 1307376Sgblack@eecs.umich.edu width = 1; 1317376Sgblack@eecs.umich.edu break; 1327376Sgblack@eecs.umich.edu } 1337376Sgblack@eecs.umich.edu M5_FALLTHROUGH; 1347376Sgblack@eecs.umich.edu default: 1357376Sgblack@eecs.umich.edu return new Unknown(machInst); 1367376Sgblack@eecs.umich.edu } 1377376Sgblack@eecs.umich.edu } 1387376Sgblack@eecs.umich.edu assert(width > 0 && width <= 4); 1397376Sgblack@eecs.umich.edu 1407376Sgblack@eecs.umich.edu const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0); 1417376Sgblack@eecs.umich.edu const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16); 1427376Sgblack@eecs.umich.edu const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) | 1437376Sgblack@eecs.umich.edu bits(machInst, 22) << 4); 1447376Sgblack@eecs.umich.edu const uint32_t type = bits(machInst, 11, 8); 1457376Sgblack@eecs.umich.edu uint32_t size = 0; 1467376Sgblack@eecs.umich.edu uint32_t align = TLB::MustBeOne; 1477376Sgblack@eecs.umich.edu unsigned inc = 1; 1487376Sgblack@eecs.umich.edu unsigned regs = 1; 1497376Sgblack@eecs.umich.edu unsigned lane = 0; 1507376Sgblack@eecs.umich.edu if (single) { 1517376Sgblack@eecs.umich.edu if (singleAll) { 1527376Sgblack@eecs.umich.edu size = bits(machInst, 7, 6); 1537376Sgblack@eecs.umich.edu bool t = bits(machInst, 5); 1547376Sgblack@eecs.umich.edu align = size | TLB::AllowUnaligned; 1557376Sgblack@eecs.umich.edu if (width == 1) { 1567376Sgblack@eecs.umich.edu regs = t ? 2 : 1; 1577376Sgblack@eecs.umich.edu inc = 1; 1587376Sgblack@eecs.umich.edu } else { 1597376Sgblack@eecs.umich.edu regs = width; 1607376Sgblack@eecs.umich.edu inc = t ? 2 : 1; 1617376Sgblack@eecs.umich.edu } 1627376Sgblack@eecs.umich.edu switch (width) { 1637376Sgblack@eecs.umich.edu case 1: 1647376Sgblack@eecs.umich.edu case 2: 1657376Sgblack@eecs.umich.edu if (bits(machInst, 4)) 1667376Sgblack@eecs.umich.edu align = size + width - 1; 1677376Sgblack@eecs.umich.edu break; 1687376Sgblack@eecs.umich.edu case 3: 1697376Sgblack@eecs.umich.edu break; 1707376Sgblack@eecs.umich.edu case 4: 1717376Sgblack@eecs.umich.edu if (size == 3) { 1727376Sgblack@eecs.umich.edu if (bits(machInst, 4) == 0) 1737376Sgblack@eecs.umich.edu return new Unknown(machInst); 1747376Sgblack@eecs.umich.edu size = 2; 1757376Sgblack@eecs.umich.edu align = 0x4; 1767376Sgblack@eecs.umich.edu } else if (size == 2) { 1777376Sgblack@eecs.umich.edu if (bits(machInst, 4)) 1787376Sgblack@eecs.umich.edu align = 0x3; 1797376Sgblack@eecs.umich.edu } else { 1807376Sgblack@eecs.umich.edu if (bits(machInst, 4)) 1817376Sgblack@eecs.umich.edu align = size + 2; 1827376Sgblack@eecs.umich.edu } 1837376Sgblack@eecs.umich.edu break; 1847376Sgblack@eecs.umich.edu } 1857376Sgblack@eecs.umich.edu } else { 1867376Sgblack@eecs.umich.edu size = bits(machInst, 11, 10); 1877376Sgblack@eecs.umich.edu align = size | TLB::AllowUnaligned; 1887322Sgblack@eecs.umich.edu regs = width; 1897322Sgblack@eecs.umich.edu unsigned indexAlign = bits(machInst, 7, 4); 1907322Sgblack@eecs.umich.edu // If width is 1, inc is always 1. That's overridden later. 1917322Sgblack@eecs.umich.edu switch (size) { 1927322Sgblack@eecs.umich.edu case 0: 1937322Sgblack@eecs.umich.edu inc = 1; 1947375Sgblack@eecs.umich.edu lane = bits(indexAlign, 3, 1); 1957322Sgblack@eecs.umich.edu break; 1967322Sgblack@eecs.umich.edu case 1: 1977375Sgblack@eecs.umich.edu inc = bits(indexAlign, 1) ? 2 : 1; 1987375Sgblack@eecs.umich.edu lane = bits(indexAlign, 3, 2); 1997322Sgblack@eecs.umich.edu break; 2007324Sgblack@eecs.umich.edu case 2: 2017375Sgblack@eecs.umich.edu inc = bits(indexAlign, 2) ? 2 : 1; 2027324Sgblack@eecs.umich.edu lane = bits(indexAlign, 3); 2037324Sgblack@eecs.umich.edu break; 2047375Sgblack@eecs.umich.edu } 2057375Sgblack@eecs.umich.edu // Override inc for width of 1. 2067324Sgblack@eecs.umich.edu if (width == 1) { 2077333Sgblack@eecs.umich.edu inc = 1; 2087333Sgblack@eecs.umich.edu } 2097333Sgblack@eecs.umich.edu switch (width) { 2107333Sgblack@eecs.umich.edu case 1: 2117375Sgblack@eecs.umich.edu switch (size) { 2127333Sgblack@eecs.umich.edu case 0: 2137333Sgblack@eecs.umich.edu break; 2147375Sgblack@eecs.umich.edu case 1: 2157375Sgblack@eecs.umich.edu if (bits(indexAlign, 0)) 2167333Sgblack@eecs.umich.edu align = 1; 2177333Sgblack@eecs.umich.edu break; 2187333Sgblack@eecs.umich.edu case 2: 2197333Sgblack@eecs.umich.edu if (bits(indexAlign, 1, 0)) 2207333Sgblack@eecs.umich.edu align = 2; 2217333Sgblack@eecs.umich.edu break; 2227375Sgblack@eecs.umich.edu } 2237333Sgblack@eecs.umich.edu break; 2247333Sgblack@eecs.umich.edu case 2: 2257375Sgblack@eecs.umich.edu if (bits(indexAlign, 0)) 2267375Sgblack@eecs.umich.edu align = size + 1; 2277333Sgblack@eecs.umich.edu break; 2287333Sgblack@eecs.umich.edu case 3: 2297333Sgblack@eecs.umich.edu break; 2307333Sgblack@eecs.umich.edu case 4: 2317333Sgblack@eecs.umich.edu switch (size) { 2327333Sgblack@eecs.umich.edu case 0: 2337333Sgblack@eecs.umich.edu case 1: 2347333Sgblack@eecs.umich.edu if (bits(indexAlign, 0)) 2357375Sgblack@eecs.umich.edu align = size + 2; 2367333Sgblack@eecs.umich.edu break; 2377333Sgblack@eecs.umich.edu case 2: 2387375Sgblack@eecs.umich.edu if (bits(indexAlign, 0)) 2397375Sgblack@eecs.umich.edu align = bits(indexAlign, 1, 0) + 2; 2407333Sgblack@eecs.umich.edu break; 2417333Sgblack@eecs.umich.edu } 2427333Sgblack@eecs.umich.edu break; 2437333Sgblack@eecs.umich.edu } 2447333Sgblack@eecs.umich.edu } 2457375Sgblack@eecs.umich.edu if (size == 0x3) { 2467333Sgblack@eecs.umich.edu return new Unknown(machInst); 2477333Sgblack@eecs.umich.edu } 2487375Sgblack@eecs.umich.edu } else { 2497375Sgblack@eecs.umich.edu size = bits(machInst, 7, 6); 2507333Sgblack@eecs.umich.edu align = bits(machInst, 5, 4); 2517333Sgblack@eecs.umich.edu if (align == 0) { 2527333Sgblack@eecs.umich.edu // @align wasn't specified, so alignment can be turned off. 2537333Sgblack@eecs.umich.edu align = size | TLB::AllowUnaligned; 2547333Sgblack@eecs.umich.edu } else { 2557333Sgblack@eecs.umich.edu align = align + 2; 2567375Sgblack@eecs.umich.edu } 2577333Sgblack@eecs.umich.edu switch (width) { 2587333Sgblack@eecs.umich.edu case 1: 2597375Sgblack@eecs.umich.edu switch (type) { 2607375Sgblack@eecs.umich.edu case 0x7: regs = 1; 2617333Sgblack@eecs.umich.edu break; 2627333Sgblack@eecs.umich.edu case 0xa: regs = 2; 2637333Sgblack@eecs.umich.edu break; 2647333Sgblack@eecs.umich.edu case 0x6: regs = 3; 2657333Sgblack@eecs.umich.edu break; 2667333Sgblack@eecs.umich.edu case 0x2: regs = 4; 2677333Sgblack@eecs.umich.edu break; 2687333Sgblack@eecs.umich.edu default: 2697375Sgblack@eecs.umich.edu return new Unknown(machInst); 2707333Sgblack@eecs.umich.edu } 2717333Sgblack@eecs.umich.edu break; 2727375Sgblack@eecs.umich.edu case 2: 2737375Sgblack@eecs.umich.edu // Regs doesn't behave exactly as it does in the manual 2747333Sgblack@eecs.umich.edu // because they loop over regs registers twice and we break 2757333Sgblack@eecs.umich.edu // it down in the macroop. 2767333Sgblack@eecs.umich.edu switch (type) { 2777333Sgblack@eecs.umich.edu case 0x8: regs = 2; inc = 1; 2787333Sgblack@eecs.umich.edu break; 2797375Sgblack@eecs.umich.edu case 0x9: regs = 2; inc = 2; 2807333Sgblack@eecs.umich.edu break; 2817333Sgblack@eecs.umich.edu case 0x3: regs = 4; inc = 2; 2827375Sgblack@eecs.umich.edu break; 2837375Sgblack@eecs.umich.edu default: 2847333Sgblack@eecs.umich.edu return new Unknown(machInst); 2857333Sgblack@eecs.umich.edu } 2867333Sgblack@eecs.umich.edu break; 2877333Sgblack@eecs.umich.edu case 3: 2887333Sgblack@eecs.umich.edu regs = 3; 2897375Sgblack@eecs.umich.edu switch (type) { 2907333Sgblack@eecs.umich.edu case 0x4: inc = 1; 2917333Sgblack@eecs.umich.edu break; 2927375Sgblack@eecs.umich.edu case 0x5: inc = 2;; 2937375Sgblack@eecs.umich.edu break; 2947333Sgblack@eecs.umich.edu default: 2957333Sgblack@eecs.umich.edu return new Unknown(machInst); 2967333Sgblack@eecs.umich.edu } 2977333Sgblack@eecs.umich.edu break; 2987333Sgblack@eecs.umich.edu case 4: 2997375Sgblack@eecs.umich.edu regs = 4; 3007333Sgblack@eecs.umich.edu switch (type) { 3017333Sgblack@eecs.umich.edu case 0: inc = 1; 3027375Sgblack@eecs.umich.edu break; 3037375Sgblack@eecs.umich.edu case 1: inc = 2; 3047333Sgblack@eecs.umich.edu break; 3057333Sgblack@eecs.umich.edu default: 3067333Sgblack@eecs.umich.edu return new Unknown(machInst); 3077333Sgblack@eecs.umich.edu } 3087333Sgblack@eecs.umich.edu break; 3097375Sgblack@eecs.umich.edu } 3107333Sgblack@eecs.umich.edu } 3117333Sgblack@eecs.umich.edu 3127375Sgblack@eecs.umich.edu if (load) { 3137375Sgblack@eecs.umich.edu // Load instructions. 3147333Sgblack@eecs.umich.edu if (single) { 3157333Sgblack@eecs.umich.edu return new VldSingle(machInst, singleAll, width, rn, vd, 3167333Sgblack@eecs.umich.edu regs, inc, size, align, rm, lane); 3177333Sgblack@eecs.umich.edu } else { 3187333Sgblack@eecs.umich.edu return new VldMult(machInst, width, rn, vd, 3197375Sgblack@eecs.umich.edu regs, inc, size, align, rm); 3207333Sgblack@eecs.umich.edu } 3217333Sgblack@eecs.umich.edu } else { 3227375Sgblack@eecs.umich.edu // Store instructions. 3237375Sgblack@eecs.umich.edu if (single) { 3247333Sgblack@eecs.umich.edu if (singleAll) { 3257333Sgblack@eecs.umich.edu return new Unknown(machInst); 3267333Sgblack@eecs.umich.edu } else { 3277333Sgblack@eecs.umich.edu return new VstSingle(machInst, false, width, rn, vd, 3287333Sgblack@eecs.umich.edu regs, inc, size, align, rm, lane); 3297375Sgblack@eecs.umich.edu } 3307333Sgblack@eecs.umich.edu } else { 3317333Sgblack@eecs.umich.edu return new VstMult(machInst, width, rn, vd, 3327375Sgblack@eecs.umich.edu regs, inc, size, align, rm); 3337375Sgblack@eecs.umich.edu } 3347333Sgblack@eecs.umich.edu } 3357333Sgblack@eecs.umich.edu return new Unknown(machInst); 3367333Sgblack@eecs.umich.edu } 3377333Sgblack@eecs.umich.edu ''' 3387333Sgblack@eecs.umich.edu 3397375Sgblack@eecs.umich.edu decoder_output += ''' 3407333Sgblack@eecs.umich.edu static StaticInstPtr 3417333Sgblack@eecs.umich.edu decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 3427375Sgblack@eecs.umich.edu { 3437375Sgblack@eecs.umich.edu const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 3447333Sgblack@eecs.umich.edu const uint32_t a = bits(machInst, 11, 8); 3457333Sgblack@eecs.umich.edu const bool b = bits(machInst, 4); 3467333Sgblack@eecs.umich.edu const uint32_t c = bits(machInst, 21, 20); 3477333Sgblack@eecs.umich.edu const IntRegIndex vd = 3487333Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 3497375Sgblack@eecs.umich.edu (bits(machInst, 22) << 4))); 3507333Sgblack@eecs.umich.edu const IntRegIndex vn = 3517333Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 19, 16) | 3527375Sgblack@eecs.umich.edu (bits(machInst, 7) << 4))); 3537375Sgblack@eecs.umich.edu const IntRegIndex vm = 3547333Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 3, 0) | 3557333Sgblack@eecs.umich.edu (bits(machInst, 5) << 4))); 3567333Sgblack@eecs.umich.edu const unsigned size = bits(machInst, 21, 20); 3577333Sgblack@eecs.umich.edu const bool q = bits(machInst, 6); 3587333Sgblack@eecs.umich.edu if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1))) 3597333Sgblack@eecs.umich.edu return new Unknown(machInst); 3607375Sgblack@eecs.umich.edu switch (a) { 3617333Sgblack@eecs.umich.edu case 0x0: 3627333Sgblack@eecs.umich.edu if (b) { 3637375Sgblack@eecs.umich.edu if (u) { 3647375Sgblack@eecs.umich.edu return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 3657333Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 3667333Sgblack@eecs.umich.edu } else { 3677333Sgblack@eecs.umich.edu return decodeNeonSThreeReg<VqaddSD, VqaddSQ>( 3687333Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 3697333Sgblack@eecs.umich.edu } 3707333Sgblack@eecs.umich.edu } else { 3717375Sgblack@eecs.umich.edu if (size == 3) 3727333Sgblack@eecs.umich.edu return new Unknown(machInst); 3737333Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VhaddD, VhaddQ>( 3747375Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 3757375Sgblack@eecs.umich.edu } 3767333Sgblack@eecs.umich.edu case 0x1: 3777381Sgblack@eecs.umich.edu if (!b) { 3787381Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>( 3797381Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 3807381Sgblack@eecs.umich.edu } else { 3817381Sgblack@eecs.umich.edu if (u) { 3827381Sgblack@eecs.umich.edu switch (c) { 3837381Sgblack@eecs.umich.edu case 0: 3847364Sgblack@eecs.umich.edu if (q) { 3857364Sgblack@eecs.umich.edu return new VeorQ<uint64_t>(machInst, vd, vn, vm); 3867382Sgblack@eecs.umich.edu } else { 3877378Sgblack@eecs.umich.edu return new VeorD<uint64_t>(machInst, vd, vn, vm); 3887381Sgblack@eecs.umich.edu } 3897385Sgblack@eecs.umich.edu case 1: 3907381Sgblack@eecs.umich.edu if (q) { 3917378Sgblack@eecs.umich.edu return new VbslQ<uint64_t>(machInst, vd, vn, vm); 3927364Sgblack@eecs.umich.edu } else { 3937364Sgblack@eecs.umich.edu return new VbslD<uint64_t>(machInst, vd, vn, vm); 3947364Sgblack@eecs.umich.edu } 3957364Sgblack@eecs.umich.edu case 2: 3967375Sgblack@eecs.umich.edu if (q) { 3977364Sgblack@eecs.umich.edu return new VbitQ<uint64_t>(machInst, vd, vn, vm); 3987364Sgblack@eecs.umich.edu } else { 3997375Sgblack@eecs.umich.edu return new VbitD<uint64_t>(machInst, vd, vn, vm); 4007375Sgblack@eecs.umich.edu } 4017364Sgblack@eecs.umich.edu case 3: 4027364Sgblack@eecs.umich.edu if (q) { 4037364Sgblack@eecs.umich.edu return new VbifQ<uint64_t>(machInst, vd, vn, vm); 4047364Sgblack@eecs.umich.edu } else { 4057364Sgblack@eecs.umich.edu return new VbifD<uint64_t>(machInst, vd, vn, vm); 4067364Sgblack@eecs.umich.edu } 4077382Sgblack@eecs.umich.edu default: 4087378Sgblack@eecs.umich.edu M5_UNREACHABLE; 4097381Sgblack@eecs.umich.edu } 4107385Sgblack@eecs.umich.edu } else { 4117381Sgblack@eecs.umich.edu switch (c) { 4127378Sgblack@eecs.umich.edu case 0: 4137364Sgblack@eecs.umich.edu if (q) { 4147364Sgblack@eecs.umich.edu return new VandQ<uint64_t>(machInst, vd, vn, vm); 4157364Sgblack@eecs.umich.edu } else { 4167364Sgblack@eecs.umich.edu return new VandD<uint64_t>(machInst, vd, vn, vm); 4177364Sgblack@eecs.umich.edu } 4187364Sgblack@eecs.umich.edu case 1: 4197364Sgblack@eecs.umich.edu if (q) { 4207375Sgblack@eecs.umich.edu return new VbicQ<uint64_t>(machInst, vd, vn, vm); 4217364Sgblack@eecs.umich.edu } else { 4227364Sgblack@eecs.umich.edu return new VbicD<uint64_t>(machInst, vd, vn, vm); 4237375Sgblack@eecs.umich.edu } 4247375Sgblack@eecs.umich.edu case 2: 4257364Sgblack@eecs.umich.edu if (vn == vm) { 4267365Sgblack@eecs.umich.edu if (q) { 4277365Sgblack@eecs.umich.edu return new VmovQ<uint64_t>( 4287365Sgblack@eecs.umich.edu machInst, vd, vn, vm); 4297365Sgblack@eecs.umich.edu } else { 4307375Sgblack@eecs.umich.edu return new VmovD<uint64_t>( 4317365Sgblack@eecs.umich.edu machInst, vd, vn, vm); 4327365Sgblack@eecs.umich.edu } 4337375Sgblack@eecs.umich.edu } else { 4347375Sgblack@eecs.umich.edu if (q) { 4357365Sgblack@eecs.umich.edu return new VorrQ<uint64_t>( 4367365Sgblack@eecs.umich.edu machInst, vd, vn, vm); 4377365Sgblack@eecs.umich.edu } else { 4387365Sgblack@eecs.umich.edu return new VorrD<uint64_t>( 4397365Sgblack@eecs.umich.edu machInst, vd, vn, vm); 4407365Sgblack@eecs.umich.edu } 4417365Sgblack@eecs.umich.edu } 4427365Sgblack@eecs.umich.edu case 3: 4437365Sgblack@eecs.umich.edu if (q) { 4447375Sgblack@eecs.umich.edu return new VornQ<uint64_t>( 4457365Sgblack@eecs.umich.edu machInst, vd, vn, vm); 4467365Sgblack@eecs.umich.edu } else { 4477375Sgblack@eecs.umich.edu return new VornD<uint64_t>( 4487375Sgblack@eecs.umich.edu machInst, vd, vn, vm); 4497365Sgblack@eecs.umich.edu } 4507366Sgblack@eecs.umich.edu default: 4517366Sgblack@eecs.umich.edu M5_UNREACHABLE; 4527366Sgblack@eecs.umich.edu } 4537366Sgblack@eecs.umich.edu } 4547375Sgblack@eecs.umich.edu } 4557366Sgblack@eecs.umich.edu case 0x2: 4567366Sgblack@eecs.umich.edu if (b) { 4577375Sgblack@eecs.umich.edu if (u) { 4587375Sgblack@eecs.umich.edu return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 4597366Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 4607366Sgblack@eecs.umich.edu } else { 4617366Sgblack@eecs.umich.edu return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 4627366Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 4637366Sgblack@eecs.umich.edu } 4647366Sgblack@eecs.umich.edu } else { 4657366Sgblack@eecs.umich.edu if (size == 3) 4667366Sgblack@eecs.umich.edu return new Unknown(machInst); 4677366Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VhsubD, VhsubQ>( 4687375Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 4697366Sgblack@eecs.umich.edu } 4707366Sgblack@eecs.umich.edu case 0x3: 4717375Sgblack@eecs.umich.edu if (b) { 4727375Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VcgeD, VcgeQ>( 4737366Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 4747367Sgblack@eecs.umich.edu } else { 4757367Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VcgtD, VcgtQ>( 4767382Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 4777378Sgblack@eecs.umich.edu } 4787381Sgblack@eecs.umich.edu case 0x4: 4797385Sgblack@eecs.umich.edu if (b) { 4807381Sgblack@eecs.umich.edu if (u) { 4817378Sgblack@eecs.umich.edu return decodeNeonUThreeReg<VqshlUD, VqshlUQ>( 4827367Sgblack@eecs.umich.edu q, size, machInst, vd, vm, vn); 4837375Sgblack@eecs.umich.edu } else { 4847367Sgblack@eecs.umich.edu return decodeNeonSThreeReg<VqshlSD, VqshlSQ>( 4857367Sgblack@eecs.umich.edu q, size, machInst, vd, vm, vn); 4867375Sgblack@eecs.umich.edu } 4877375Sgblack@eecs.umich.edu } else { 4887367Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VshlD, VshlQ>( 4897367Sgblack@eecs.umich.edu q, u, size, machInst, vd, vm, vn); 4907367Sgblack@eecs.umich.edu } 4917367Sgblack@eecs.umich.edu case 0x5: 4927367Sgblack@eecs.umich.edu if (b) { 4937367Sgblack@eecs.umich.edu if (u) { 4947385Sgblack@eecs.umich.edu return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>( 4957385Sgblack@eecs.umich.edu q, size, machInst, vd, vm, vn); 4967382Sgblack@eecs.umich.edu } else { 4977378Sgblack@eecs.umich.edu return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>( 4987381Sgblack@eecs.umich.edu q, size, machInst, vd, vm, vn); 4997385Sgblack@eecs.umich.edu } 5007385Sgblack@eecs.umich.edu } else { 5017381Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 5027378Sgblack@eecs.umich.edu q, u, size, machInst, vd, vm, vn); 5037367Sgblack@eecs.umich.edu } 5047367Sgblack@eecs.umich.edu case 0x6: 5057367Sgblack@eecs.umich.edu if (b) { 5067375Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VminD, VminQ>( 5077367Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5087367Sgblack@eecs.umich.edu } else { 5097375Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VmaxD, VmaxQ>( 5107375Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5117367Sgblack@eecs.umich.edu } 5127368Sgblack@eecs.umich.edu case 0x7: 5137368Sgblack@eecs.umich.edu if (b) { 5147382Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VabaD, VabaQ>( 5157378Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5167381Sgblack@eecs.umich.edu } else { 5177385Sgblack@eecs.umich.edu if (bits(machInst, 23) == 1) { 5187381Sgblack@eecs.umich.edu if (q) { 5197378Sgblack@eecs.umich.edu return new Unknown(machInst); 5207368Sgblack@eecs.umich.edu } else { 5217375Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vabdl>( 5227368Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 5237368Sgblack@eecs.umich.edu } 5247375Sgblack@eecs.umich.edu } else { 5257375Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VabdD, VabdQ>( 5267368Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5277368Sgblack@eecs.umich.edu } 5287368Sgblack@eecs.umich.edu } 5297368Sgblack@eecs.umich.edu case 0x8: 5307368Sgblack@eecs.umich.edu if (b) { 5317368Sgblack@eecs.umich.edu if (u) { 5327382Sgblack@eecs.umich.edu return decodeNeonUThreeReg<VceqD, VceqQ>( 5337378Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5347381Sgblack@eecs.umich.edu } else { 5357385Sgblack@eecs.umich.edu return decodeNeonUThreeReg<VtstD, VtstQ>( 5367381Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5377378Sgblack@eecs.umich.edu } 5387368Sgblack@eecs.umich.edu } else { 5397368Sgblack@eecs.umich.edu if (u) { 5407368Sgblack@eecs.umich.edu return decodeNeonUThreeReg<NVsubD, NVsubQ>( 5417375Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5427368Sgblack@eecs.umich.edu } else { 5437368Sgblack@eecs.umich.edu return decodeNeonUThreeReg<NVaddD, NVaddQ>( 5447375Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5457375Sgblack@eecs.umich.edu } 5467368Sgblack@eecs.umich.edu } 5477369Sgblack@eecs.umich.edu case 0x9: 5487369Sgblack@eecs.umich.edu if (b) { 5497382Sgblack@eecs.umich.edu if (u) { 5507378Sgblack@eecs.umich.edu return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 5517381Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5527385Sgblack@eecs.umich.edu } else { 5537381Sgblack@eecs.umich.edu return decodeNeonSThreeReg<NVmulD, NVmulQ>( 5547378Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5557369Sgblack@eecs.umich.edu } 5567375Sgblack@eecs.umich.edu } else { 5577369Sgblack@eecs.umich.edu if (u) { 5587369Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 5597375Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5607375Sgblack@eecs.umich.edu } else { 5617369Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 5627369Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5637369Sgblack@eecs.umich.edu } 5647369Sgblack@eecs.umich.edu } 5657369Sgblack@eecs.umich.edu case 0xa: 5667369Sgblack@eecs.umich.edu if (q) 5677382Sgblack@eecs.umich.edu return new Unknown(machInst); 5687378Sgblack@eecs.umich.edu if (b) { 5697381Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<VpminD>( 5707385Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 5717381Sgblack@eecs.umich.edu } else { 5727378Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<VpmaxD>( 5737369Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 5747369Sgblack@eecs.umich.edu } 5757369Sgblack@eecs.umich.edu case 0xb: 5767375Sgblack@eecs.umich.edu if (b) { 5777369Sgblack@eecs.umich.edu if (u || q) { 5787369Sgblack@eecs.umich.edu return new Unknown(machInst); 5797375Sgblack@eecs.umich.edu } else { 5807375Sgblack@eecs.umich.edu return decodeNeonUThreeUSReg<NVpaddD>( 5817369Sgblack@eecs.umich.edu size, machInst, vd, vn, vm); 5827369Sgblack@eecs.umich.edu } 5837369Sgblack@eecs.umich.edu } else { 5847382Sgblack@eecs.umich.edu if (u) { 5857378Sgblack@eecs.umich.edu return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>( 5867381Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5877369Sgblack@eecs.umich.edu } else { 5887381Sgblack@eecs.umich.edu return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>( 5897378Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5907369Sgblack@eecs.umich.edu } 5917369Sgblack@eecs.umich.edu } 5927369Sgblack@eecs.umich.edu case 0xc: 5937369Sgblack@eecs.umich.edu if (b) { 5947375Sgblack@eecs.umich.edu if (!u) { 5957369Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 5967369Sgblack@eecs.umich.edu if (q) { 5977375Sgblack@eecs.umich.edu return new NVfmaQFp<float>(machInst, vd, vn, vm); 5987375Sgblack@eecs.umich.edu } else { 5997369Sgblack@eecs.umich.edu return new NVfmaDFp<float>(machInst, vd, vn, vm); 6007369Sgblack@eecs.umich.edu } 6017369Sgblack@eecs.umich.edu } else { 6027369Sgblack@eecs.umich.edu if (q) { 6037369Sgblack@eecs.umich.edu return new NVfmsQFp<float>(machInst, vd, vn, vm); 6047382Sgblack@eecs.umich.edu } else { 6057378Sgblack@eecs.umich.edu return new NVfmsDFp<float>(machInst, vd, vn, vm); 6067381Sgblack@eecs.umich.edu } 6077369Sgblack@eecs.umich.edu } 6087381Sgblack@eecs.umich.edu } 6097378Sgblack@eecs.umich.edu } 6107369Sgblack@eecs.umich.edu return new Unknown(machInst); 6117369Sgblack@eecs.umich.edu case 0xd: 6127369Sgblack@eecs.umich.edu if (b) { 6137369Sgblack@eecs.umich.edu if (u) { 6147369Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 6157369Sgblack@eecs.umich.edu if (q) { 6167375Sgblack@eecs.umich.edu return new NVmulQFp<float>(machInst, vd, vn, vm); 6177369Sgblack@eecs.umich.edu } else { 6187369Sgblack@eecs.umich.edu return new NVmulDFp<float>(machInst, vd, vn, vm); 6197375Sgblack@eecs.umich.edu } 6207375Sgblack@eecs.umich.edu } else { 6217369Sgblack@eecs.umich.edu return new Unknown(machInst); 6227381Sgblack@eecs.umich.edu } 6237381Sgblack@eecs.umich.edu } else { 6247381Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 6257381Sgblack@eecs.umich.edu if (q) { 6267381Sgblack@eecs.umich.edu return new NVmlaQFp<float>(machInst, vd, vn, vm); 6277381Sgblack@eecs.umich.edu } else { 6287381Sgblack@eecs.umich.edu return new NVmlaDFp<float>(machInst, vd, vn, vm); 6297370Sgblack@eecs.umich.edu } 6307370Sgblack@eecs.umich.edu } else { 6317382Sgblack@eecs.umich.edu if (q) { 6327378Sgblack@eecs.umich.edu return new NVmlsQFp<float>(machInst, vd, vn, vm); 6337381Sgblack@eecs.umich.edu } else { 6347385Sgblack@eecs.umich.edu return new NVmlsDFp<float>(machInst, vd, vn, vm); 6357370Sgblack@eecs.umich.edu } 6367370Sgblack@eecs.umich.edu } 6377370Sgblack@eecs.umich.edu } 6387382Sgblack@eecs.umich.edu } else { 6397385Sgblack@eecs.umich.edu if (u) { 6407381Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 6417378Sgblack@eecs.umich.edu if (q) { 6427370Sgblack@eecs.umich.edu return new VpaddQFp<float>(machInst, vd, vn, vm); 6437375Sgblack@eecs.umich.edu } else { 6447370Sgblack@eecs.umich.edu return new VpaddDFp<float>(machInst, vd, vn, vm); 6457370Sgblack@eecs.umich.edu } 6467375Sgblack@eecs.umich.edu } else { 6477375Sgblack@eecs.umich.edu if (q) { 6487370Sgblack@eecs.umich.edu return new VabdQFp<float>(machInst, vd, vn, vm); 6497370Sgblack@eecs.umich.edu } else { 6507370Sgblack@eecs.umich.edu return new VabdDFp<float>(machInst, vd, vn, vm); 6517370Sgblack@eecs.umich.edu } 6527370Sgblack@eecs.umich.edu } 6537370Sgblack@eecs.umich.edu } else { 6547370Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 6557382Sgblack@eecs.umich.edu if (q) { 6567378Sgblack@eecs.umich.edu return new VaddQFp<float>(machInst, vd, vn, vm); 6577381Sgblack@eecs.umich.edu } else { 6587385Sgblack@eecs.umich.edu return new VaddDFp<float>(machInst, vd, vn, vm); 6597370Sgblack@eecs.umich.edu } 6607370Sgblack@eecs.umich.edu } else { 6617370Sgblack@eecs.umich.edu if (q) { 6627370Sgblack@eecs.umich.edu return new VsubQFp<float>(machInst, vd, vn, vm); 6637382Sgblack@eecs.umich.edu } else { 6647385Sgblack@eecs.umich.edu return new VsubDFp<float>(machInst, vd, vn, vm); 6657381Sgblack@eecs.umich.edu } 6667378Sgblack@eecs.umich.edu } 6677370Sgblack@eecs.umich.edu } 6687370Sgblack@eecs.umich.edu } 6697370Sgblack@eecs.umich.edu case 0xe: 6707375Sgblack@eecs.umich.edu if (b) { 6717370Sgblack@eecs.umich.edu if (u) { 6727370Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 6737375Sgblack@eecs.umich.edu if (q) { 6747375Sgblack@eecs.umich.edu return new VacgeQFp<float>(machInst, vd, vn, vm); 6757370Sgblack@eecs.umich.edu } else { 6767370Sgblack@eecs.umich.edu return new VacgeDFp<float>(machInst, vd, vn, vm); 6777370Sgblack@eecs.umich.edu } 6787382Sgblack@eecs.umich.edu } else { 6797378Sgblack@eecs.umich.edu if (q) { 6807381Sgblack@eecs.umich.edu return new VacgtQFp<float>(machInst, vd, vn, vm); 6817385Sgblack@eecs.umich.edu } else { 6827370Sgblack@eecs.umich.edu return new VacgtDFp<float>(machInst, vd, vn, vm); 6837370Sgblack@eecs.umich.edu } 6847370Sgblack@eecs.umich.edu } 6857382Sgblack@eecs.umich.edu } else { 6867385Sgblack@eecs.umich.edu return new Unknown(machInst); 6877381Sgblack@eecs.umich.edu } 6887378Sgblack@eecs.umich.edu } else { 6897370Sgblack@eecs.umich.edu if (u) { 6907375Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 6917370Sgblack@eecs.umich.edu if (q) { 6927370Sgblack@eecs.umich.edu return new VcgeQFp<float>(machInst, vd, vn, vm); 6937375Sgblack@eecs.umich.edu } else { 6947375Sgblack@eecs.umich.edu return new VcgeDFp<float>(machInst, vd, vn, vm); 6957370Sgblack@eecs.umich.edu } 6967370Sgblack@eecs.umich.edu } else { 6977370Sgblack@eecs.umich.edu if (q) { 6987370Sgblack@eecs.umich.edu return new VcgtQFp<float>(machInst, vd, vn, vm); 6997370Sgblack@eecs.umich.edu } else { 7007370Sgblack@eecs.umich.edu return new VcgtDFp<float>(machInst, vd, vn, vm); 7017370Sgblack@eecs.umich.edu } 7027382Sgblack@eecs.umich.edu } 7037378Sgblack@eecs.umich.edu } else { 7047381Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 7057385Sgblack@eecs.umich.edu if (q) { 7067370Sgblack@eecs.umich.edu return new VceqQFp<float>(machInst, vd, vn, vm); 7077370Sgblack@eecs.umich.edu } else { 7087370Sgblack@eecs.umich.edu return new VceqDFp<float>(machInst, vd, vn, vm); 7097370Sgblack@eecs.umich.edu } 7107385Sgblack@eecs.umich.edu } else { 7117382Sgblack@eecs.umich.edu return new Unknown(machInst); 7127381Sgblack@eecs.umich.edu } 7137378Sgblack@eecs.umich.edu } 7147370Sgblack@eecs.umich.edu } 7157370Sgblack@eecs.umich.edu case 0xf: 7167370Sgblack@eecs.umich.edu if (b) { 7177375Sgblack@eecs.umich.edu if (u) { 7187370Sgblack@eecs.umich.edu return new Unknown(machInst); 7197370Sgblack@eecs.umich.edu } else { 7207375Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 7217375Sgblack@eecs.umich.edu if (q) { 7227370Sgblack@eecs.umich.edu return new VrecpsQFp<float>(machInst, vd, vn, vm); 7237371Sgblack@eecs.umich.edu } else { 7247371Sgblack@eecs.umich.edu return new VrecpsDFp<float>(machInst, vd, vn, vm); 7257382Sgblack@eecs.umich.edu } 7267378Sgblack@eecs.umich.edu } else { 7277381Sgblack@eecs.umich.edu if (q) { 7287385Sgblack@eecs.umich.edu return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 7297371Sgblack@eecs.umich.edu } else { 7307371Sgblack@eecs.umich.edu return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 7317371Sgblack@eecs.umich.edu } 7327382Sgblack@eecs.umich.edu } 7337385Sgblack@eecs.umich.edu } 7347381Sgblack@eecs.umich.edu } else { 7357378Sgblack@eecs.umich.edu if (u) { 7367371Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 7377375Sgblack@eecs.umich.edu if (q) { 7387371Sgblack@eecs.umich.edu return new VpmaxQFp<float>(machInst, vd, vn, vm); 7397371Sgblack@eecs.umich.edu } else { 7407375Sgblack@eecs.umich.edu return new VpmaxDFp<float>(machInst, vd, vn, vm); 7417375Sgblack@eecs.umich.edu } 7427371Sgblack@eecs.umich.edu } else { 7437371Sgblack@eecs.umich.edu if (q) { 7447371Sgblack@eecs.umich.edu return new VpminQFp<float>(machInst, vd, vn, vm); 7457371Sgblack@eecs.umich.edu } else { 7467371Sgblack@eecs.umich.edu return new VpminDFp<float>(machInst, vd, vn, vm); 7477371Sgblack@eecs.umich.edu } 7487371Sgblack@eecs.umich.edu } 7497382Sgblack@eecs.umich.edu } else { 7507378Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 7517381Sgblack@eecs.umich.edu if (q) { 7527385Sgblack@eecs.umich.edu return new VmaxQFp<float>(machInst, vd, vn, vm); 7537371Sgblack@eecs.umich.edu } else { 7547371Sgblack@eecs.umich.edu return new VmaxDFp<float>(machInst, vd, vn, vm); 7557371Sgblack@eecs.umich.edu } 7567371Sgblack@eecs.umich.edu } else { 7577382Sgblack@eecs.umich.edu if (q) { 7587385Sgblack@eecs.umich.edu return new VminQFp<float>(machInst, vd, vn, vm); 7597381Sgblack@eecs.umich.edu } else { 7607378Sgblack@eecs.umich.edu return new VminDFp<float>(machInst, vd, vn, vm); 7617371Sgblack@eecs.umich.edu } 7627371Sgblack@eecs.umich.edu } 7637371Sgblack@eecs.umich.edu } 7647375Sgblack@eecs.umich.edu } 7657371Sgblack@eecs.umich.edu } 7667371Sgblack@eecs.umich.edu return new Unknown(machInst); 7677375Sgblack@eecs.umich.edu } 7687375Sgblack@eecs.umich.edu 7697371Sgblack@eecs.umich.edu static StaticInstPtr 7707371Sgblack@eecs.umich.edu decodeNeonOneRegModImm(ExtMachInst machInst) 7717371Sgblack@eecs.umich.edu { 7727382Sgblack@eecs.umich.edu const IntRegIndex vd = 7737378Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 7747381Sgblack@eecs.umich.edu (bits(machInst, 22) << 4))); 7757385Sgblack@eecs.umich.edu const bool q = bits(machInst, 6); 7767371Sgblack@eecs.umich.edu const bool op = bits(machInst, 5); 7777371Sgblack@eecs.umich.edu const uint8_t cmode = bits(machInst, 11, 8); 7787371Sgblack@eecs.umich.edu const uint8_t imm = ((THUMB ? bits(machInst, 28) : 7797382Sgblack@eecs.umich.edu bits(machInst, 24)) << 7) | 7807385Sgblack@eecs.umich.edu (bits(machInst, 18, 16) << 4) | 7817381Sgblack@eecs.umich.edu (bits(machInst, 3, 0) << 0); 7827378Sgblack@eecs.umich.edu 7837371Sgblack@eecs.umich.edu // Check for invalid immediate encodings and return an unknown op 7847375Sgblack@eecs.umich.edu // if it happens 7857371Sgblack@eecs.umich.edu bool immValid = true; 7867371Sgblack@eecs.umich.edu const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid); 7877375Sgblack@eecs.umich.edu if (!immValid) { 7887375Sgblack@eecs.umich.edu return new Unknown(machInst); 7897371Sgblack@eecs.umich.edu } 7907371Sgblack@eecs.umich.edu 7917371Sgblack@eecs.umich.edu if (op) { 7927371Sgblack@eecs.umich.edu if (bits(cmode, 3) == 0) { 7937371Sgblack@eecs.umich.edu if (bits(cmode, 0) == 0) { 7947371Sgblack@eecs.umich.edu if (q) 7957371Sgblack@eecs.umich.edu return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 7967382Sgblack@eecs.umich.edu else 7977378Sgblack@eecs.umich.edu return new NVmvniD<uint64_t>(machInst, vd, bigImm); 7987381Sgblack@eecs.umich.edu } else { 7997385Sgblack@eecs.umich.edu if (q) 8007371Sgblack@eecs.umich.edu return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 8017371Sgblack@eecs.umich.edu else 8027371Sgblack@eecs.umich.edu return new NVbiciD<uint64_t>(machInst, vd, bigImm); 8037371Sgblack@eecs.umich.edu } 8047382Sgblack@eecs.umich.edu } else { 8057385Sgblack@eecs.umich.edu if (bits(cmode, 2) == 1) { 8067381Sgblack@eecs.umich.edu switch (bits(cmode, 1, 0)) { 8077378Sgblack@eecs.umich.edu case 0: 8087371Sgblack@eecs.umich.edu case 1: 8097371Sgblack@eecs.umich.edu if (q) 8107371Sgblack@eecs.umich.edu return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 8117375Sgblack@eecs.umich.edu else 8127371Sgblack@eecs.umich.edu return new NVmvniD<uint64_t>(machInst, vd, bigImm); 8137371Sgblack@eecs.umich.edu case 2: 8147375Sgblack@eecs.umich.edu if (q) 8157375Sgblack@eecs.umich.edu return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8167371Sgblack@eecs.umich.edu else 8177371Sgblack@eecs.umich.edu return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8187371Sgblack@eecs.umich.edu case 3: 8197382Sgblack@eecs.umich.edu if (q) 8207378Sgblack@eecs.umich.edu return new Unknown(machInst); 8217381Sgblack@eecs.umich.edu else 8227385Sgblack@eecs.umich.edu return new Unknown(machInst); 8237371Sgblack@eecs.umich.edu } 8247371Sgblack@eecs.umich.edu } else { 8257371Sgblack@eecs.umich.edu if (bits(cmode, 0) == 0) { 8267371Sgblack@eecs.umich.edu if (q) 8277381Sgblack@eecs.umich.edu return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 8287378Sgblack@eecs.umich.edu else 8297371Sgblack@eecs.umich.edu return new NVmvniD<uint64_t>(machInst, vd, bigImm); 8307375Sgblack@eecs.umich.edu } else { 8317371Sgblack@eecs.umich.edu if (q) 8327371Sgblack@eecs.umich.edu return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 8337375Sgblack@eecs.umich.edu else 8347375Sgblack@eecs.umich.edu return new NVbiciD<uint64_t>(machInst, vd, bigImm); 8357371Sgblack@eecs.umich.edu } 8367371Sgblack@eecs.umich.edu } 8377371Sgblack@eecs.umich.edu } 8387371Sgblack@eecs.umich.edu } else { 8397371Sgblack@eecs.umich.edu if (bits(cmode, 3) == 0) { 8407371Sgblack@eecs.umich.edu if (bits(cmode, 0) == 0) { 8417371Sgblack@eecs.umich.edu if (q) 8427382Sgblack@eecs.umich.edu return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8437378Sgblack@eecs.umich.edu else 8447381Sgblack@eecs.umich.edu return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8457385Sgblack@eecs.umich.edu } else { 8467371Sgblack@eecs.umich.edu if (q) 8477371Sgblack@eecs.umich.edu return new NVorriQ<uint64_t>(machInst, vd, bigImm); 8487371Sgblack@eecs.umich.edu else 8497371Sgblack@eecs.umich.edu return new NVorriD<uint64_t>(machInst, vd, bigImm); 8507371Sgblack@eecs.umich.edu } 8517381Sgblack@eecs.umich.edu } else { 8527378Sgblack@eecs.umich.edu if (bits(cmode, 2) == 1) { 8537371Sgblack@eecs.umich.edu if (q) 8547371Sgblack@eecs.umich.edu return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8557371Sgblack@eecs.umich.edu else 8567375Sgblack@eecs.umich.edu return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8577371Sgblack@eecs.umich.edu } else { 8587371Sgblack@eecs.umich.edu if (bits(cmode, 0) == 0) { 8597375Sgblack@eecs.umich.edu if (q) 8607375Sgblack@eecs.umich.edu return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8617371Sgblack@eecs.umich.edu else 8627381Sgblack@eecs.umich.edu return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8637381Sgblack@eecs.umich.edu } else { 8647381Sgblack@eecs.umich.edu if (q) 8657381Sgblack@eecs.umich.edu return new NVorriQ<uint64_t>(machInst, vd, bigImm); 8667381Sgblack@eecs.umich.edu else 8677381Sgblack@eecs.umich.edu return new NVorriD<uint64_t>(machInst, vd, bigImm); 8687381Sgblack@eecs.umich.edu } 8697373Sgblack@eecs.umich.edu } 8707373Sgblack@eecs.umich.edu } 8717378Sgblack@eecs.umich.edu } 8727381Sgblack@eecs.umich.edu return new Unknown(machInst); 8737373Sgblack@eecs.umich.edu } 8747381Sgblack@eecs.umich.edu 8757378Sgblack@eecs.umich.edu static StaticInstPtr 8767373Sgblack@eecs.umich.edu decodeNeonTwoRegAndShift(ExtMachInst machInst) 8777375Sgblack@eecs.umich.edu { 8787373Sgblack@eecs.umich.edu const uint32_t a = bits(machInst, 11, 8); 8797373Sgblack@eecs.umich.edu const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 8807375Sgblack@eecs.umich.edu const bool b = bits(machInst, 6); 8817375Sgblack@eecs.umich.edu const bool l = bits(machInst, 7); 8827373Sgblack@eecs.umich.edu const IntRegIndex vd = 8837373Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 8847373Sgblack@eecs.umich.edu (bits(machInst, 22) << 4))); 8857373Sgblack@eecs.umich.edu const IntRegIndex vm = 8867378Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 3, 0) | 8877381Sgblack@eecs.umich.edu (bits(machInst, 5) << 4))); 8887373Sgblack@eecs.umich.edu unsigned imm6 = bits(machInst, 21, 16); 8897381Sgblack@eecs.umich.edu unsigned imm = ((l ? 1 : 0) << 6) | imm6; 8907378Sgblack@eecs.umich.edu unsigned size = 3; 8917373Sgblack@eecs.umich.edu unsigned lShiftAmt = 0; 8927373Sgblack@eecs.umich.edu unsigned bitSel; 8937373Sgblack@eecs.umich.edu for (bitSel = 1 << 6; true; bitSel >>= 1) { 8947375Sgblack@eecs.umich.edu if (bitSel & imm) 8957373Sgblack@eecs.umich.edu break; 8967373Sgblack@eecs.umich.edu else if (!size) 8977375Sgblack@eecs.umich.edu return new Unknown(machInst); 8987375Sgblack@eecs.umich.edu size--; 8997373Sgblack@eecs.umich.edu } 9007373Sgblack@eecs.umich.edu lShiftAmt = imm6 & ~bitSel; 9017373Sgblack@eecs.umich.edu unsigned rShiftAmt = 0; 9027378Sgblack@eecs.umich.edu if (a != 0xe && a != 0xf) { 9037381Sgblack@eecs.umich.edu if (size > 2) 9047373Sgblack@eecs.umich.edu rShiftAmt = 64 - imm6; 9057381Sgblack@eecs.umich.edu else 9067378Sgblack@eecs.umich.edu rShiftAmt = 2 * (8 << size) - imm6; 9077373Sgblack@eecs.umich.edu } 9087375Sgblack@eecs.umich.edu 9097373Sgblack@eecs.umich.edu switch (a) { 9107373Sgblack@eecs.umich.edu case 0x0: 9117375Sgblack@eecs.umich.edu return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 9127375Sgblack@eecs.umich.edu b, u, size, machInst, vd, vm, rShiftAmt); 9137373Sgblack@eecs.umich.edu case 0x1: 9147373Sgblack@eecs.umich.edu return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 9157373Sgblack@eecs.umich.edu b, u, size, machInst, vd, vm, rShiftAmt); 9167373Sgblack@eecs.umich.edu case 0x2: 9177378Sgblack@eecs.umich.edu return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 9187381Sgblack@eecs.umich.edu b, u, size, machInst, vd, vm, rShiftAmt); 9197373Sgblack@eecs.umich.edu case 0x3: 9207381Sgblack@eecs.umich.edu return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 9217378Sgblack@eecs.umich.edu b, u, size, machInst, vd, vm, rShiftAmt); 9227373Sgblack@eecs.umich.edu case 0x4: 9237373Sgblack@eecs.umich.edu if (u) { 9247373Sgblack@eecs.umich.edu return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 9257375Sgblack@eecs.umich.edu b, size, machInst, vd, vm, rShiftAmt); 9267373Sgblack@eecs.umich.edu } else { 9277373Sgblack@eecs.umich.edu return new Unknown(machInst); 9287375Sgblack@eecs.umich.edu } 9297375Sgblack@eecs.umich.edu case 0x5: 9307373Sgblack@eecs.umich.edu if (u) { 9317373Sgblack@eecs.umich.edu return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 9327380Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9337382Sgblack@eecs.umich.edu } else { 9347380Sgblack@eecs.umich.edu return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 9357381Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9367380Sgblack@eecs.umich.edu } 9377381Sgblack@eecs.umich.edu case 0x6: 9387380Sgblack@eecs.umich.edu case 0x7: 9397380Sgblack@eecs.umich.edu if (u) { 9407380Sgblack@eecs.umich.edu if (a == 0x6) { 9417380Sgblack@eecs.umich.edu return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 9427380Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9437380Sgblack@eecs.umich.edu } else { 9447380Sgblack@eecs.umich.edu return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 9457380Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9467380Sgblack@eecs.umich.edu } 9477380Sgblack@eecs.umich.edu } else { 9487380Sgblack@eecs.umich.edu return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 9497380Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9507382Sgblack@eecs.umich.edu } 9517380Sgblack@eecs.umich.edu case 0x8: 9527381Sgblack@eecs.umich.edu if (l) { 9537380Sgblack@eecs.umich.edu return new Unknown(machInst); 9547381Sgblack@eecs.umich.edu } else if (u) { 9557380Sgblack@eecs.umich.edu return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 9567380Sgblack@eecs.umich.edu b, size, machInst, vd, vm, rShiftAmt); 9577380Sgblack@eecs.umich.edu } else { 9587380Sgblack@eecs.umich.edu return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 9597380Sgblack@eecs.umich.edu b, size, machInst, vd, vm, rShiftAmt); 9607380Sgblack@eecs.umich.edu } 9617380Sgblack@eecs.umich.edu case 0x9: 9627380Sgblack@eecs.umich.edu if (l) { 9637380Sgblack@eecs.umich.edu return new Unknown(machInst); 9647380Sgblack@eecs.umich.edu } else if (u) { 9657380Sgblack@eecs.umich.edu return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 9667382Sgblack@eecs.umich.edu b, size, machInst, vd, vm, rShiftAmt); 9677380Sgblack@eecs.umich.edu } else { 9687381Sgblack@eecs.umich.edu return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 9697380Sgblack@eecs.umich.edu b, size, machInst, vd, vm, rShiftAmt); 9707381Sgblack@eecs.umich.edu } 9717380Sgblack@eecs.umich.edu case 0xa: 9727380Sgblack@eecs.umich.edu if (l || b) { 9737380Sgblack@eecs.umich.edu return new Unknown(machInst); 9747380Sgblack@eecs.umich.edu } else { 9757380Sgblack@eecs.umich.edu return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 9767380Sgblack@eecs.umich.edu lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); 9777380Sgblack@eecs.umich.edu } 9787380Sgblack@eecs.umich.edu case 0xe: 9797380Sgblack@eecs.umich.edu if (l) { 9807380Sgblack@eecs.umich.edu return new Unknown(machInst); 9817380Sgblack@eecs.umich.edu } else { 9827380Sgblack@eecs.umich.edu if (bits(imm6, 5) == 0) 9837382Sgblack@eecs.umich.edu return new Unknown(machInst); 9847380Sgblack@eecs.umich.edu if (u) { 9857381Sgblack@eecs.umich.edu if (b) { 9867380Sgblack@eecs.umich.edu return new NVcvtu2fpQ<float>( 9877381Sgblack@eecs.umich.edu machInst, vd, vm, 64 - imm6); 9887380Sgblack@eecs.umich.edu } else { 9897380Sgblack@eecs.umich.edu return new NVcvtu2fpD<float>( 9907380Sgblack@eecs.umich.edu machInst, vd, vm, 64 - imm6); 9917380Sgblack@eecs.umich.edu } 9927380Sgblack@eecs.umich.edu } else { 9937380Sgblack@eecs.umich.edu if (b) { 9947380Sgblack@eecs.umich.edu return new NVcvts2fpQ<float>( 9957380Sgblack@eecs.umich.edu machInst, vd, vm, 64 - imm6); 9967380Sgblack@eecs.umich.edu } else { 9977380Sgblack@eecs.umich.edu return new NVcvts2fpD<float>( 9987373Sgblack@eecs.umich.edu machInst, vd, vm, 64 - imm6); 9997382Sgblack@eecs.umich.edu } 10007378Sgblack@eecs.umich.edu } 10017380Sgblack@eecs.umich.edu } 10027381Sgblack@eecs.umich.edu case 0xf: 10037373Sgblack@eecs.umich.edu if (l) { 10047381Sgblack@eecs.umich.edu return new Unknown(machInst); 10057378Sgblack@eecs.umich.edu } else { 10067373Sgblack@eecs.umich.edu if (bits(imm6, 5) == 0) 10077375Sgblack@eecs.umich.edu return new Unknown(machInst); 10087373Sgblack@eecs.umich.edu if (u) { 10097373Sgblack@eecs.umich.edu if (b) { 10107375Sgblack@eecs.umich.edu return new NVcvt2ufxQ<float>( 10117375Sgblack@eecs.umich.edu machInst, vd, vm, 64 - imm6); 10127373Sgblack@eecs.umich.edu } else { 10137373Sgblack@eecs.umich.edu return new NVcvt2ufxD<float>( 10147373Sgblack@eecs.umich.edu machInst, vd, vm, 64 - imm6); 10157373Sgblack@eecs.umich.edu } 10167373Sgblack@eecs.umich.edu } else { 10177382Sgblack@eecs.umich.edu if (b) { 10187378Sgblack@eecs.umich.edu return new NVcvt2sfxQ<float>( 10197380Sgblack@eecs.umich.edu machInst, vd, vm, 64 - imm6); 10207381Sgblack@eecs.umich.edu } else { 10217373Sgblack@eecs.umich.edu return new NVcvt2sfxD<float>( 10227381Sgblack@eecs.umich.edu machInst, vd, vm, 64 - imm6); 10237378Sgblack@eecs.umich.edu } 10247373Sgblack@eecs.umich.edu } 10257373Sgblack@eecs.umich.edu } 10267375Sgblack@eecs.umich.edu } 10277373Sgblack@eecs.umich.edu return new Unknown(machInst); 10287373Sgblack@eecs.umich.edu } 10297375Sgblack@eecs.umich.edu 10307375Sgblack@eecs.umich.edu static StaticInstPtr 10317373Sgblack@eecs.umich.edu decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 10327373Sgblack@eecs.umich.edu { 10337373Sgblack@eecs.umich.edu const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 10347382Sgblack@eecs.umich.edu const uint32_t a = bits(machInst, 11, 8); 10357378Sgblack@eecs.umich.edu const IntRegIndex vd = 10367380Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 10377381Sgblack@eecs.umich.edu (bits(machInst, 22) << 4))); 10387373Sgblack@eecs.umich.edu const IntRegIndex vn = 10397381Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 19, 16) | 10407378Sgblack@eecs.umich.edu (bits(machInst, 7) << 4))); 10417373Sgblack@eecs.umich.edu const IntRegIndex vm = 10427375Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 3, 0) | 10437373Sgblack@eecs.umich.edu (bits(machInst, 5) << 4))); 10447373Sgblack@eecs.umich.edu const unsigned size = bits(machInst, 21, 20); 10457375Sgblack@eecs.umich.edu switch (a) { 10467375Sgblack@eecs.umich.edu case 0x0: 10477373Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vaddl>( 10487373Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 10497373Sgblack@eecs.umich.edu case 0x1: 10507373Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vaddw>( 10517373Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 10527382Sgblack@eecs.umich.edu case 0x2: 10537378Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vsubl>( 10547380Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 10557381Sgblack@eecs.umich.edu case 0x3: 10567373Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vsubw>( 10577381Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 10587378Sgblack@eecs.umich.edu case 0x4: 10597373Sgblack@eecs.umich.edu if (u) { 10607373Sgblack@eecs.umich.edu return decodeNeonUThreeUSReg<Vraddhn>( 10617375Sgblack@eecs.umich.edu size, machInst, vd, vn, vm); 10627373Sgblack@eecs.umich.edu } else { 10637373Sgblack@eecs.umich.edu return decodeNeonUThreeUSReg<Vaddhn>( 10647375Sgblack@eecs.umich.edu size, machInst, vd, vn, vm); 10657375Sgblack@eecs.umich.edu } 10667373Sgblack@eecs.umich.edu case 0x5: 10677374Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vabal>( 10687374Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 10697374Sgblack@eecs.umich.edu case 0x6: 10707382Sgblack@eecs.umich.edu if (u) { 10717378Sgblack@eecs.umich.edu return decodeNeonUThreeUSReg<Vrsubhn>( 10727381Sgblack@eecs.umich.edu size, machInst, vd, vn, vm); 10737374Sgblack@eecs.umich.edu } else { 10747381Sgblack@eecs.umich.edu return decodeNeonUThreeUSReg<Vsubhn>( 10757378Sgblack@eecs.umich.edu size, machInst, vd, vn, vm); 10767374Sgblack@eecs.umich.edu } 10777374Sgblack@eecs.umich.edu case 0x7: 10787374Sgblack@eecs.umich.edu if (bits(machInst, 23)) { 10797375Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vabdl>( 10807374Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 10817374Sgblack@eecs.umich.edu } else { 10827375Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VabdD, VabdQ>( 10837375Sgblack@eecs.umich.edu bits(machInst, 6), u, size, machInst, vd, vn, vm); 10847374Sgblack@eecs.umich.edu } 10857374Sgblack@eecs.umich.edu case 0x8: 10867374Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vmlal>( 10877374Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 10887374Sgblack@eecs.umich.edu case 0xa: 10897382Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vmlsl>( 10907378Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 10917381Sgblack@eecs.umich.edu case 0x9: 10927374Sgblack@eecs.umich.edu if (u) { 10937381Sgblack@eecs.umich.edu return new Unknown(machInst); 10947378Sgblack@eecs.umich.edu } else { 10957374Sgblack@eecs.umich.edu return decodeNeonSThreeUSReg<Vqdmlal>( 10967375Sgblack@eecs.umich.edu size, machInst, vd, vn, vm); 10977374Sgblack@eecs.umich.edu } 10987374Sgblack@eecs.umich.edu case 0xb: 10997375Sgblack@eecs.umich.edu if (u) { 11007375Sgblack@eecs.umich.edu return new Unknown(machInst); 11017374Sgblack@eecs.umich.edu } else { 11027377Sgblack@eecs.umich.edu return decodeNeonSThreeUSReg<Vqdmlsl>( 11037377Sgblack@eecs.umich.edu size, machInst, vd, vn, vm); 11047377Sgblack@eecs.umich.edu } 11057382Sgblack@eecs.umich.edu case 0xc: 11067377Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vmull>( 11077377Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 11087377Sgblack@eecs.umich.edu case 0xd: 11097377Sgblack@eecs.umich.edu if (u) { 11107377Sgblack@eecs.umich.edu return new Unknown(machInst); 11117377Sgblack@eecs.umich.edu } else { 11127377Sgblack@eecs.umich.edu return decodeNeonSThreeUSReg<Vqdmull>( 11137377Sgblack@eecs.umich.edu size, machInst, vd, vn, vm); 11147377Sgblack@eecs.umich.edu } 11157377Sgblack@eecs.umich.edu case 0xe: 11167377Sgblack@eecs.umich.edu return decodeNeonUThreeUSReg<Vmullp>( 11177377Sgblack@eecs.umich.edu size, machInst, vd, vn, vm); 11187377Sgblack@eecs.umich.edu } 11197377Sgblack@eecs.umich.edu return new Unknown(machInst); 11207377Sgblack@eecs.umich.edu } 11217377Sgblack@eecs.umich.edu 11227377Sgblack@eecs.umich.edu static StaticInstPtr 11237377Sgblack@eecs.umich.edu decodeNeonTwoRegScalar(ExtMachInst machInst) 11247377Sgblack@eecs.umich.edu { 11257377Sgblack@eecs.umich.edu const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 11267377Sgblack@eecs.umich.edu const uint32_t a = bits(machInst, 11, 8); 11277377Sgblack@eecs.umich.edu const unsigned size = bits(machInst, 21, 20); 11287382Sgblack@eecs.umich.edu const IntRegIndex vd = 11297377Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 11307377Sgblack@eecs.umich.edu (bits(machInst, 22) << 4))); 11317377Sgblack@eecs.umich.edu const IntRegIndex vn = 11327377Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 19, 16) | 11337377Sgblack@eecs.umich.edu (bits(machInst, 7) << 4))); 11347377Sgblack@eecs.umich.edu const IntRegIndex vm = (size == 2) ? 11357377Sgblack@eecs.umich.edu (IntRegIndex)(2 * bits(machInst, 3, 0)) : 11367377Sgblack@eecs.umich.edu (IntRegIndex)(2 * bits(machInst, 2, 0)); 11377377Sgblack@eecs.umich.edu const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 11387377Sgblack@eecs.umich.edu (bits(machInst, 3) | (bits(machInst, 5) << 1)); 11397377Sgblack@eecs.umich.edu switch (a) { 11407377Sgblack@eecs.umich.edu case 0x0: 11417377Sgblack@eecs.umich.edu if (u) { 11427377Sgblack@eecs.umich.edu switch (size) { 11437377Sgblack@eecs.umich.edu case 1: 11447377Sgblack@eecs.umich.edu return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 11457377Sgblack@eecs.umich.edu case 2: 11467377Sgblack@eecs.umich.edu return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index); 11477377Sgblack@eecs.umich.edu default: 11487377Sgblack@eecs.umich.edu return new Unknown(machInst); 11497377Sgblack@eecs.umich.edu } 11507382Sgblack@eecs.umich.edu } else { 11517377Sgblack@eecs.umich.edu switch (size) { 11527377Sgblack@eecs.umich.edu case 1: 11537377Sgblack@eecs.umich.edu return new VmlasD<uint16_t>(machInst, vd, vn, vm, index); 11547377Sgblack@eecs.umich.edu case 2: 11557377Sgblack@eecs.umich.edu return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 11567377Sgblack@eecs.umich.edu default: 11577377Sgblack@eecs.umich.edu return new Unknown(machInst); 11587377Sgblack@eecs.umich.edu } 11597377Sgblack@eecs.umich.edu } 11607377Sgblack@eecs.umich.edu case 0x1: 11617377Sgblack@eecs.umich.edu if (u) 11627377Sgblack@eecs.umich.edu return new VmlasQFp<float>(machInst, vd, vn, vm, index); 11637377Sgblack@eecs.umich.edu else 11647377Sgblack@eecs.umich.edu return new VmlasDFp<float>(machInst, vd, vn, vm, index); 11657377Sgblack@eecs.umich.edu case 0x4: 11667377Sgblack@eecs.umich.edu if (u) { 11677377Sgblack@eecs.umich.edu switch (size) { 11687377Sgblack@eecs.umich.edu case 1: 11697377Sgblack@eecs.umich.edu return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 11707377Sgblack@eecs.umich.edu case 2: 11717377Sgblack@eecs.umich.edu return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index); 11727382Sgblack@eecs.umich.edu default: 11737377Sgblack@eecs.umich.edu return new Unknown(machInst); 11747377Sgblack@eecs.umich.edu } 11757377Sgblack@eecs.umich.edu } else { 11767377Sgblack@eecs.umich.edu switch (size) { 11777377Sgblack@eecs.umich.edu case 1: 11787377Sgblack@eecs.umich.edu return new VmlssD<uint16_t>(machInst, vd, vn, vm, index); 11797377Sgblack@eecs.umich.edu case 2: 11807377Sgblack@eecs.umich.edu return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 11817377Sgblack@eecs.umich.edu default: 11827377Sgblack@eecs.umich.edu return new Unknown(machInst); 11837377Sgblack@eecs.umich.edu } 11847377Sgblack@eecs.umich.edu } 11857377Sgblack@eecs.umich.edu case 0x5: 11867377Sgblack@eecs.umich.edu if (u) 11877377Sgblack@eecs.umich.edu return new VmlssQFp<float>(machInst, vd, vn, vm, index); 11887377Sgblack@eecs.umich.edu else 11897377Sgblack@eecs.umich.edu return new VmlssDFp<float>(machInst, vd, vn, vm, index); 11907377Sgblack@eecs.umich.edu case 0x2: 11917322Sgblack@eecs.umich.edu if (u) { 11927379Sgblack@eecs.umich.edu switch (size) { 11937379Sgblack@eecs.umich.edu case 1: 11947379Sgblack@eecs.umich.edu return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 11957379Sgblack@eecs.umich.edu case 2: 11967379Sgblack@eecs.umich.edu return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 11977379Sgblack@eecs.umich.edu default: 11987379Sgblack@eecs.umich.edu return new Unknown(machInst); 11997379Sgblack@eecs.umich.edu } 12007382Sgblack@eecs.umich.edu } else { 12017379Sgblack@eecs.umich.edu switch (size) { 12027381Sgblack@eecs.umich.edu case 1: 12037379Sgblack@eecs.umich.edu return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 12047381Sgblack@eecs.umich.edu case 2: 12057379Sgblack@eecs.umich.edu return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 12067379Sgblack@eecs.umich.edu default: 12077379Sgblack@eecs.umich.edu return new Unknown(machInst); 12087379Sgblack@eecs.umich.edu } 12097379Sgblack@eecs.umich.edu } 12107379Sgblack@eecs.umich.edu case 0x6: 12117379Sgblack@eecs.umich.edu if (u) { 12127379Sgblack@eecs.umich.edu switch (size) { 12137379Sgblack@eecs.umich.edu case 1: 12147379Sgblack@eecs.umich.edu return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 12157379Sgblack@eecs.umich.edu case 2: 12167379Sgblack@eecs.umich.edu return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 12177382Sgblack@eecs.umich.edu default: 12187379Sgblack@eecs.umich.edu return new Unknown(machInst); 12197381Sgblack@eecs.umich.edu } 12207379Sgblack@eecs.umich.edu } else { 12217381Sgblack@eecs.umich.edu switch (size) { 12227379Sgblack@eecs.umich.edu case 1: 12237379Sgblack@eecs.umich.edu return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 12247379Sgblack@eecs.umich.edu case 2: 12257379Sgblack@eecs.umich.edu return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 12267379Sgblack@eecs.umich.edu default: 12277379Sgblack@eecs.umich.edu return new Unknown(machInst); 12287379Sgblack@eecs.umich.edu } 12297379Sgblack@eecs.umich.edu } 12307379Sgblack@eecs.umich.edu case 0x3: 12317379Sgblack@eecs.umich.edu if (u) { 12327379Sgblack@eecs.umich.edu return new Unknown(machInst); 12337379Sgblack@eecs.umich.edu } else { 12347382Sgblack@eecs.umich.edu switch (size) { 12357379Sgblack@eecs.umich.edu case 1: 12367381Sgblack@eecs.umich.edu return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 12377379Sgblack@eecs.umich.edu case 2: 12387381Sgblack@eecs.umich.edu return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 12397379Sgblack@eecs.umich.edu default: 12407379Sgblack@eecs.umich.edu return new Unknown(machInst); 12417379Sgblack@eecs.umich.edu } 12427379Sgblack@eecs.umich.edu } 12437379Sgblack@eecs.umich.edu case 0x7: 12447379Sgblack@eecs.umich.edu if (u) { 12457379Sgblack@eecs.umich.edu return new Unknown(machInst); 12467379Sgblack@eecs.umich.edu } else { 12477379Sgblack@eecs.umich.edu switch (size) { 12487379Sgblack@eecs.umich.edu case 1: 12497379Sgblack@eecs.umich.edu return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 12507379Sgblack@eecs.umich.edu case 2: 12517382Sgblack@eecs.umich.edu return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 12527379Sgblack@eecs.umich.edu default: 12537381Sgblack@eecs.umich.edu return new Unknown(machInst); 12547379Sgblack@eecs.umich.edu } 12557381Sgblack@eecs.umich.edu } 12567379Sgblack@eecs.umich.edu case 0x8: 12577379Sgblack@eecs.umich.edu if (u) { 12587379Sgblack@eecs.umich.edu switch (size) { 12597379Sgblack@eecs.umich.edu case 1: 12607379Sgblack@eecs.umich.edu return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 12617379Sgblack@eecs.umich.edu case 2: 12627379Sgblack@eecs.umich.edu return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index); 12637379Sgblack@eecs.umich.edu default: 12647379Sgblack@eecs.umich.edu return new Unknown(machInst); 12657379Sgblack@eecs.umich.edu } 12667379Sgblack@eecs.umich.edu } else { 12677379Sgblack@eecs.umich.edu switch (size) { 12687379Sgblack@eecs.umich.edu case 1: 12697381Sgblack@eecs.umich.edu return new VmulsD<uint16_t>(machInst, vd, vn, vm, index); 12707380Sgblack@eecs.umich.edu case 2: 12717381Sgblack@eecs.umich.edu return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 12727379Sgblack@eecs.umich.edu default: 12737379Sgblack@eecs.umich.edu return new Unknown(machInst); 12747379Sgblack@eecs.umich.edu } 12757379Sgblack@eecs.umich.edu } 12767379Sgblack@eecs.umich.edu case 0x9: 12777379Sgblack@eecs.umich.edu if (u) 12787379Sgblack@eecs.umich.edu return new VmulsQFp<float>(machInst, vd, vn, vm, index); 12797379Sgblack@eecs.umich.edu else 12807379Sgblack@eecs.umich.edu return new VmulsDFp<float>(machInst, vd, vn, vm, index); 12817379Sgblack@eecs.umich.edu case 0xa: 12827379Sgblack@eecs.umich.edu if (u) { 12837379Sgblack@eecs.umich.edu switch (size) { 12847379Sgblack@eecs.umich.edu case 1: 12857381Sgblack@eecs.umich.edu return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 12867380Sgblack@eecs.umich.edu case 2: 12877381Sgblack@eecs.umich.edu return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 12887379Sgblack@eecs.umich.edu default: 12897379Sgblack@eecs.umich.edu return new Unknown(machInst); 12907379Sgblack@eecs.umich.edu } 12917379Sgblack@eecs.umich.edu } else { 12927379Sgblack@eecs.umich.edu switch (size) { 12937379Sgblack@eecs.umich.edu case 1: 12947379Sgblack@eecs.umich.edu return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 12957379Sgblack@eecs.umich.edu case 2: 12967379Sgblack@eecs.umich.edu return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 12977379Sgblack@eecs.umich.edu default: 12987379Sgblack@eecs.umich.edu return new Unknown(machInst); 12997379Sgblack@eecs.umich.edu } 13007379Sgblack@eecs.umich.edu } 13017381Sgblack@eecs.umich.edu case 0xb: 13027379Sgblack@eecs.umich.edu if (u) { 13037381Sgblack@eecs.umich.edu return new Unknown(machInst); 13047379Sgblack@eecs.umich.edu } else { 13057379Sgblack@eecs.umich.edu if (u) { 13067379Sgblack@eecs.umich.edu switch (size) { 13077379Sgblack@eecs.umich.edu case 1: 13087379Sgblack@eecs.umich.edu return new Vqdmulls<uint16_t>( 13097379Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13107379Sgblack@eecs.umich.edu case 2: 13117379Sgblack@eecs.umich.edu return new Vqdmulls<uint32_t>( 13127379Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13137379Sgblack@eecs.umich.edu default: 13147379Sgblack@eecs.umich.edu return new Unknown(machInst); 13157379Sgblack@eecs.umich.edu } 13167379Sgblack@eecs.umich.edu } else { 13177381Sgblack@eecs.umich.edu switch (size) { 13187379Sgblack@eecs.umich.edu case 1: 13197381Sgblack@eecs.umich.edu return new Vqdmulls<int16_t>( 13207379Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13217379Sgblack@eecs.umich.edu case 2: 13227379Sgblack@eecs.umich.edu return new Vqdmulls<int32_t>( 13237379Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13247379Sgblack@eecs.umich.edu default: 13257379Sgblack@eecs.umich.edu return new Unknown(machInst); 13267379Sgblack@eecs.umich.edu } 13277379Sgblack@eecs.umich.edu } 13287379Sgblack@eecs.umich.edu } 13297379Sgblack@eecs.umich.edu case 0xc: 13307379Sgblack@eecs.umich.edu if (u) { 13317379Sgblack@eecs.umich.edu switch (size) { 13327382Sgblack@eecs.umich.edu case 1: 13337379Sgblack@eecs.umich.edu return new VqdmulhsQ<int16_t>( 13347381Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13357379Sgblack@eecs.umich.edu case 2: 13367381Sgblack@eecs.umich.edu return new VqdmulhsQ<int32_t>( 13377379Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13387379Sgblack@eecs.umich.edu default: 13397379Sgblack@eecs.umich.edu return new Unknown(machInst); 13407379Sgblack@eecs.umich.edu } 13417379Sgblack@eecs.umich.edu } else { 13427379Sgblack@eecs.umich.edu switch (size) { 13437379Sgblack@eecs.umich.edu case 1: 13447379Sgblack@eecs.umich.edu return new VqdmulhsD<int16_t>( 13457379Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13467379Sgblack@eecs.umich.edu case 2: 13477379Sgblack@eecs.umich.edu return new VqdmulhsD<int32_t>( 13487379Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13497379Sgblack@eecs.umich.edu default: 13507382Sgblack@eecs.umich.edu return new Unknown(machInst); 13517379Sgblack@eecs.umich.edu } 13527381Sgblack@eecs.umich.edu } 13537379Sgblack@eecs.umich.edu case 0xd: 13547381Sgblack@eecs.umich.edu if (u) { 13557379Sgblack@eecs.umich.edu switch (size) { 13567379Sgblack@eecs.umich.edu case 1: 13577379Sgblack@eecs.umich.edu return new VqrdmulhsQ<int16_t>( 13587379Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13597379Sgblack@eecs.umich.edu case 2: 13607379Sgblack@eecs.umich.edu return new VqrdmulhsQ<int32_t>( 13617379Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13627379Sgblack@eecs.umich.edu default: 13637379Sgblack@eecs.umich.edu return new Unknown(machInst); 13647379Sgblack@eecs.umich.edu } 13657379Sgblack@eecs.umich.edu } else { 13667379Sgblack@eecs.umich.edu switch (size) { 13677379Sgblack@eecs.umich.edu case 1: 13687382Sgblack@eecs.umich.edu return new VqrdmulhsD<int16_t>( 13697379Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13707381Sgblack@eecs.umich.edu case 2: 13717379Sgblack@eecs.umich.edu return new VqrdmulhsD<int32_t>( 13727381Sgblack@eecs.umich.edu machInst, vd, vn, vm, index); 13737379Sgblack@eecs.umich.edu default: 13747379Sgblack@eecs.umich.edu return new Unknown(machInst); 13757379Sgblack@eecs.umich.edu } 13767379Sgblack@eecs.umich.edu } 13777379Sgblack@eecs.umich.edu } 13787379Sgblack@eecs.umich.edu return new Unknown(machInst); 13797379Sgblack@eecs.umich.edu } 13807379Sgblack@eecs.umich.edu 13817379Sgblack@eecs.umich.edu static StaticInstPtr 13827379Sgblack@eecs.umich.edu decodeNeonTwoRegMisc(ExtMachInst machInst) 13837379Sgblack@eecs.umich.edu { 13847379Sgblack@eecs.umich.edu const uint32_t a = bits(machInst, 17, 16); 13857379Sgblack@eecs.umich.edu const uint32_t b = bits(machInst, 10, 6); 13867382Sgblack@eecs.umich.edu const bool q = bits(machInst, 6); 13877379Sgblack@eecs.umich.edu const IntRegIndex vd = 13887381Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 13897379Sgblack@eecs.umich.edu (bits(machInst, 22) << 4))); 13907381Sgblack@eecs.umich.edu const IntRegIndex vm = 13917379Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 3, 0) | 13927379Sgblack@eecs.umich.edu (bits(machInst, 5) << 4))); 13937379Sgblack@eecs.umich.edu const unsigned size = bits(machInst, 19, 18); 13947379Sgblack@eecs.umich.edu switch (a) { 13957379Sgblack@eecs.umich.edu case 0x0: 13967379Sgblack@eecs.umich.edu switch (bits(b, 4, 1)) { 13977379Sgblack@eecs.umich.edu case 0x0: 13987379Sgblack@eecs.umich.edu switch (size) { 13997379Sgblack@eecs.umich.edu case 0: 14007379Sgblack@eecs.umich.edu if (q) { 14017379Sgblack@eecs.umich.edu return new NVrev64Q<uint8_t>(machInst, vd, vm); 14027379Sgblack@eecs.umich.edu } else { 14037379Sgblack@eecs.umich.edu return new NVrev64D<uint8_t>(machInst, vd, vm); 14047379Sgblack@eecs.umich.edu } 14057381Sgblack@eecs.umich.edu case 1: 14067379Sgblack@eecs.umich.edu if (q) { 14077381Sgblack@eecs.umich.edu return new NVrev64Q<uint16_t>(machInst, vd, vm); 14087379Sgblack@eecs.umich.edu } else { 14097379Sgblack@eecs.umich.edu return new NVrev64D<uint16_t>(machInst, vd, vm); 14107379Sgblack@eecs.umich.edu } 14117379Sgblack@eecs.umich.edu case 2: 14127379Sgblack@eecs.umich.edu if (q) { 14137379Sgblack@eecs.umich.edu return new NVrev64Q<uint32_t>(machInst, vd, vm); 14147379Sgblack@eecs.umich.edu } else { 14157379Sgblack@eecs.umich.edu return new NVrev64D<uint32_t>(machInst, vd, vm); 14167379Sgblack@eecs.umich.edu } 14177379Sgblack@eecs.umich.edu default: 14187379Sgblack@eecs.umich.edu return new Unknown(machInst); 14197379Sgblack@eecs.umich.edu } 14207379Sgblack@eecs.umich.edu case 0x1: 14217379Sgblack@eecs.umich.edu switch (size) { 14227381Sgblack@eecs.umich.edu case 0: 14237379Sgblack@eecs.umich.edu if (q) { 14247381Sgblack@eecs.umich.edu return new NVrev32Q<uint8_t>(machInst, vd, vm); 14257379Sgblack@eecs.umich.edu } else { 14267379Sgblack@eecs.umich.edu return new NVrev32D<uint8_t>(machInst, vd, vm); 14277379Sgblack@eecs.umich.edu } 14287379Sgblack@eecs.umich.edu case 1: 14297379Sgblack@eecs.umich.edu if (q) { 14307379Sgblack@eecs.umich.edu return new NVrev32Q<uint16_t>(machInst, vd, vm); 14317379Sgblack@eecs.umich.edu } else { 14327379Sgblack@eecs.umich.edu return new NVrev32D<uint16_t>(machInst, vd, vm); 14337379Sgblack@eecs.umich.edu } 14347379Sgblack@eecs.umich.edu default: 14357379Sgblack@eecs.umich.edu return new Unknown(machInst); 14367379Sgblack@eecs.umich.edu } 14377379Sgblack@eecs.umich.edu case 0x2: 14387379Sgblack@eecs.umich.edu if (size != 0) { 14397381Sgblack@eecs.umich.edu return new Unknown(machInst); 14407379Sgblack@eecs.umich.edu } else if (q) { 14417381Sgblack@eecs.umich.edu return new NVrev16Q<uint8_t>(machInst, vd, vm); 14427379Sgblack@eecs.umich.edu } else { 14437379Sgblack@eecs.umich.edu return new NVrev16D<uint8_t>(machInst, vd, vm); 14447379Sgblack@eecs.umich.edu } 14457379Sgblack@eecs.umich.edu case 0x4: 14467379Sgblack@eecs.umich.edu return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 14477379Sgblack@eecs.umich.edu q, size, machInst, vd, vm); 14487379Sgblack@eecs.umich.edu case 0x5: 14497379Sgblack@eecs.umich.edu return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 14507379Sgblack@eecs.umich.edu q, size, machInst, vd, vm); 14517379Sgblack@eecs.umich.edu case 0x8: 14527379Sgblack@eecs.umich.edu return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 14537379Sgblack@eecs.umich.edu q, size, machInst, vd, vm); 14547379Sgblack@eecs.umich.edu case 0x9: 14557379Sgblack@eecs.umich.edu return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 14567381Sgblack@eecs.umich.edu q, size, machInst, vd, vm); 14577379Sgblack@eecs.umich.edu case 0xa: 14587381Sgblack@eecs.umich.edu return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 14597379Sgblack@eecs.umich.edu q, size, machInst, vd, vm); 14607379Sgblack@eecs.umich.edu case 0xb: 14617379Sgblack@eecs.umich.edu if (q) 14627379Sgblack@eecs.umich.edu return new NVmvnQ<uint64_t>(machInst, vd, vm); 14637379Sgblack@eecs.umich.edu else 14647379Sgblack@eecs.umich.edu return new NVmvnD<uint64_t>(machInst, vd, vm); 14657379Sgblack@eecs.umich.edu case 0xc: 14667379Sgblack@eecs.umich.edu return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 14677379Sgblack@eecs.umich.edu q, size, machInst, vd, vm); 14687379Sgblack@eecs.umich.edu case 0xd: 14697379Sgblack@eecs.umich.edu return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 14707379Sgblack@eecs.umich.edu q, size, machInst, vd, vm); 1471 case 0xe: 1472 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 1473 q, size, machInst, vd, vm); 1474 case 0xf: 1475 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 1476 q, size, machInst, vd, vm); 1477 default: 1478 return new Unknown(machInst); 1479 } 1480 case 0x1: 1481 switch (bits(b, 3, 1)) { 1482 case 0x0: 1483 if (bits(b, 4)) { 1484 if (q) { 1485 return new NVcgtQFp<float>(machInst, vd, vm); 1486 } else { 1487 return new NVcgtDFp<float>(machInst, vd, vm); 1488 } 1489 } else { 1490 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 1491 q, size, machInst, vd, vm); 1492 } 1493 case 0x1: 1494 if (bits(b, 4)) { 1495 if (q) { 1496 return new NVcgeQFp<float>(machInst, vd, vm); 1497 } else { 1498 return new NVcgeDFp<float>(machInst, vd, vm); 1499 } 1500 } else { 1501 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 1502 q, size, machInst, vd, vm); 1503 } 1504 case 0x2: 1505 if (bits(b, 4)) { 1506 if (q) { 1507 return new NVceqQFp<float>(machInst, vd, vm); 1508 } else { 1509 return new NVceqDFp<float>(machInst, vd, vm); 1510 } 1511 } else { 1512 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 1513 q, size, machInst, vd, vm); 1514 } 1515 case 0x3: 1516 if (bits(b, 4)) { 1517 if (q) { 1518 return new NVcleQFp<float>(machInst, vd, vm); 1519 } else { 1520 return new NVcleDFp<float>(machInst, vd, vm); 1521 } 1522 } else { 1523 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 1524 q, size, machInst, vd, vm); 1525 } 1526 case 0x4: 1527 if (bits(b, 4)) { 1528 if (q) { 1529 return new NVcltQFp<float>(machInst, vd, vm); 1530 } else { 1531 return new NVcltDFp<float>(machInst, vd, vm); 1532 } 1533 } else { 1534 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 1535 q, size, machInst, vd, vm); 1536 } 1537 case 0x6: 1538 if (bits(machInst, 10)) { 1539 if (q) 1540 return new NVabsQFp<float>(machInst, vd, vm); 1541 else 1542 return new NVabsDFp<float>(machInst, vd, vm); 1543 } else { 1544 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 1545 q, size, machInst, vd, vm); 1546 } 1547 case 0x7: 1548 if (bits(machInst, 10)) { 1549 if (q) 1550 return new NVnegQFp<float>(machInst, vd, vm); 1551 else 1552 return new NVnegDFp<float>(machInst, vd, vm); 1553 } else { 1554 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 1555 q, size, machInst, vd, vm); 1556 } 1557 default: 1558 return new Unknown64(machInst); 1559 } 1560 case 0x2: 1561 switch (bits(b, 4, 1)) { 1562 case 0x0: 1563 if (q) 1564 return new NVswpQ<uint64_t>(machInst, vd, vm); 1565 else 1566 return new NVswpD<uint64_t>(machInst, vd, vm); 1567 case 0x1: 1568 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>( 1569 q, size, machInst, vd, vm); 1570 case 0x2: 1571 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 1572 q, size, machInst, vd, vm); 1573 case 0x3: 1574 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 1575 q, size, machInst, vd, vm); 1576 case 0x4: 1577 if (b == 0x8) { 1578 return decodeNeonUTwoMiscUSReg<NVmovn>( 1579 size, machInst, vd, vm); 1580 } else { 1581 return decodeNeonSTwoMiscUSReg<NVqmovuns>( 1582 size, machInst, vd, vm); 1583 } 1584 case 0x5: 1585 if (q) { 1586 return decodeNeonUTwoMiscUSReg<NVqmovun>( 1587 size, machInst, vd, vm); 1588 } else { 1589 return decodeNeonSTwoMiscUSReg<NVqmovn>( 1590 size, machInst, vd, vm); 1591 } 1592 case 0x6: 1593 if (b == 0xc) { 1594 return decodeNeonSTwoShiftUSReg<NVshll>( 1595 size, machInst, vd, vm, 8 << size); 1596 } else { 1597 return new Unknown(machInst); 1598 } 1599 case 0xc: 1600 case 0xe: 1601 if (b == 0x18) { 1602 if (size != 1 || (vm % 2)) 1603 return new Unknown(machInst); 1604 return new NVcvts2h<uint16_t>(machInst, vd, vm); 1605 } else if (b == 0x1c) { 1606 if (size != 1 || (vd % 2)) 1607 return new Unknown(machInst); 1608 return new NVcvth2s<uint16_t>(machInst, vd, vm); 1609 } else { 1610 return new Unknown(machInst); 1611 } 1612 default: 1613 return new Unknown(machInst); 1614 } 1615 case 0x3: 1616 if (bits(b, 4, 3) == 0x3) { 1617 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1618 return new Unknown(machInst); 1619 } else { 1620 if (bits(b, 2)) { 1621 if (bits(b, 1)) { 1622 if (q) { 1623 return new NVcvt2ufxQ<float>( 1624 machInst, vd, vm, 0); 1625 } else { 1626 return new NVcvt2ufxD<float>( 1627 machInst, vd, vm, 0); 1628 } 1629 } else { 1630 if (q) { 1631 return new NVcvt2sfxQ<float>( 1632 machInst, vd, vm, 0); 1633 } else { 1634 return new NVcvt2sfxD<float>( 1635 machInst, vd, vm, 0); 1636 } 1637 } 1638 } else { 1639 if (bits(b, 1)) { 1640 if (q) { 1641 return new NVcvtu2fpQ<float>( 1642 machInst, vd, vm, 0); 1643 } else { 1644 return new NVcvtu2fpD<float>( 1645 machInst, vd, vm, 0); 1646 } 1647 } else { 1648 if (q) { 1649 return new NVcvts2fpQ<float>( 1650 machInst, vd, vm, 0); 1651 } else { 1652 return new NVcvts2fpD<float>( 1653 machInst, vd, vm, 0); 1654 } 1655 } 1656 } 1657 } 1658 } else if ((b & 0x1a) == 0x10) { 1659 if (bits(b, 2)) { 1660 if (q) { 1661 return new NVrecpeQFp<float>(machInst, vd, vm); 1662 } else { 1663 return new NVrecpeDFp<float>(machInst, vd, vm); 1664 } 1665 } else { 1666 if (q) { 1667 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1668 } else { 1669 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1670 } 1671 } 1672 } else if ((b & 0x1a) == 0x12) { 1673 if (bits(b, 2)) { 1674 if (q) { 1675 return new NVrsqrteQFp<float>(machInst, vd, vm); 1676 } else { 1677 return new NVrsqrteDFp<float>(machInst, vd, vm); 1678 } 1679 } else { 1680 if (q) { 1681 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1682 } else { 1683 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1684 } 1685 } 1686 } else { 1687 return new Unknown(machInst); 1688 } 1689 } 1690 return new Unknown(machInst); 1691 } 1692 1693 StaticInstPtr 1694 decodeNeonData(ExtMachInst machInst) 1695 { 1696 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1697 const uint32_t a = bits(machInst, 23, 19); 1698 const uint32_t b = bits(machInst, 11, 8); 1699 const uint32_t c = bits(machInst, 7, 4); 1700 if (bits(a, 4) == 0) { 1701 return decodeNeonThreeRegistersSameLength(machInst); 1702 } else if ((c & 0x9) == 1) { 1703 if ((a & 0x7) == 0) { 1704 return decodeNeonOneRegModImm(machInst); 1705 } else { 1706 return decodeNeonTwoRegAndShift(machInst); 1707 } 1708 } else if ((c & 0x9) == 9) { 1709 return decodeNeonTwoRegAndShift(machInst); 1710 } else if (bits(a, 2, 1) != 0x3) { 1711 if ((c & 0x5) == 0) { 1712 return decodeNeonThreeRegDiffLengths(machInst); 1713 } else if ((c & 0x5) == 4) { 1714 return decodeNeonTwoRegScalar(machInst); 1715 } 1716 } else if ((a & 0x16) == 0x16) { 1717 const IntRegIndex vd = 1718 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1719 (bits(machInst, 22) << 4))); 1720 const IntRegIndex vn = 1721 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1722 (bits(machInst, 7) << 4))); 1723 const IntRegIndex vm = 1724 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1725 (bits(machInst, 5) << 4))); 1726 if (!u) { 1727 if (bits(c, 0) == 0) { 1728 unsigned imm4 = bits(machInst, 11, 8); 1729 bool q = bits(machInst, 6); 1730 if (imm4 >= 16 && !q) 1731 return new Unknown(machInst); 1732 if (q) { 1733 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1734 } else { 1735 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1736 } 1737 } 1738 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1739 return decodeNeonTwoRegMisc(machInst); 1740 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { 1741 unsigned length = bits(machInst, 9, 8) + 1; 1742 if ((uint32_t)vn / 2 + length > 32) 1743 return new Unknown(machInst); 1744 if (bits(machInst, 6) == 0) { 1745 switch (length) { 1746 case 1: 1747 return new NVtbl1(machInst, vd, vn, vm); 1748 case 2: 1749 return new NVtbl2(machInst, vd, vn, vm); 1750 case 3: 1751 return new NVtbl3(machInst, vd, vn, vm); 1752 case 4: 1753 return new NVtbl4(machInst, vd, vn, vm); 1754 } 1755 } else { 1756 switch (length) { 1757 case 1: 1758 return new NVtbx1(machInst, vd, vn, vm); 1759 case 2: 1760 return new NVtbx2(machInst, vd, vn, vm); 1761 case 3: 1762 return new NVtbx3(machInst, vd, vn, vm); 1763 case 4: 1764 return new NVtbx4(machInst, vd, vn, vm); 1765 } 1766 } 1767 } else if (b == 0xc && (c & 0x9) == 0) { 1768 unsigned imm4 = bits(machInst, 19, 16); 1769 if (bits(imm4, 2, 0) == 0) 1770 return new Unknown(machInst); 1771 unsigned size = 0; 1772 while ((imm4 & 0x1) == 0) { 1773 size++; 1774 imm4 >>= 1; 1775 } 1776 unsigned index = imm4 >> 1; 1777 const bool q = bits(machInst, 6); 1778 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1779 q, size, machInst, vd, vm, index); 1780 } 1781 } 1782 return new Unknown(machInst); 1783 } 1784 ''' 1785}}; 1786 1787def format ThumbNeonMem() {{ 1788 decode_block = ''' 1789 return decodeNeonMem(machInst); 1790 ''' 1791}}; 1792 1793def format ThumbNeonData() {{ 1794 decode_block = ''' 1795 return decodeNeonData(machInst); 1796 ''' 1797}}; 1798 1799let {{ 1800 header_output = ''' 1801 StaticInstPtr 1802 decodeExtensionRegLoadStore(ExtMachInst machInst); 1803 ''' 1804 decoder_output = ''' 1805 StaticInstPtr 1806 decodeExtensionRegLoadStore(ExtMachInst machInst) 1807 { 1808 const uint32_t opcode = bits(machInst, 24, 20); 1809 const uint32_t offset = bits(machInst, 7, 0); 1810 const bool single = (bits(machInst, 8) == 0); 1811 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1812 RegIndex vd; 1813 if (single) { 1814 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1815 bits(machInst, 22)); 1816 } else { 1817 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1818 (bits(machInst, 22) << 5)); 1819 } 1820 switch (bits(opcode, 4, 3)) { 1821 case 0x0: 1822 if (bits(opcode, 4, 1) == 0x2 && 1823 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1824 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1825 if ((bits(machInst, 7, 4) & 0xd) != 1) { 1826 break; 1827 } 1828 const IntRegIndex rt = 1829 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1830 const IntRegIndex rt2 = 1831 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1832 const bool op = bits(machInst, 20); 1833 uint32_t vm; 1834 if (single) { 1835 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1836 } else { 1837 vm = (bits(machInst, 3, 0) << 1) | 1838 (bits(machInst, 5) << 5); 1839 } 1840 if (op) { 1841 return new Vmov2Core2Reg(machInst, rt, rt2, 1842 (IntRegIndex)vm); 1843 } else { 1844 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1845 rt, rt2); 1846 } 1847 } 1848 break; 1849 case 0x1: 1850 { 1851 if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) { 1852 break; 1853 } 1854 switch (bits(opcode, 1, 0)) { 1855 case 0x0: 1856 return new VLdmStm(machInst, rn, vd, single, 1857 true, false, false, offset); 1858 case 0x1: 1859 return new VLdmStm(machInst, rn, vd, single, 1860 true, false, true, offset); 1861 case 0x2: 1862 return new VLdmStm(machInst, rn, vd, single, 1863 true, true, false, offset); 1864 case 0x3: 1865 // If rn == sp, then this is called vpop. 1866 return new VLdmStm(machInst, rn, vd, single, 1867 true, true, true, offset); 1868 default: 1869 M5_UNREACHABLE; 1870 } 1871 } 1872 case 0x2: 1873 if (bits(opcode, 1, 0) == 0x2) { 1874 // If rn == sp, then this is called vpush. 1875 return new VLdmStm(machInst, rn, vd, single, 1876 false, true, false, offset); 1877 } else if (bits(opcode, 1, 0) == 0x3) { 1878 return new VLdmStm(machInst, rn, vd, single, 1879 false, true, true, offset); 1880 } 1881 M5_FALLTHROUGH; 1882 case 0x3: 1883 const bool up = (bits(machInst, 23) == 1); 1884 const uint32_t imm = bits(machInst, 7, 0) << 2; 1885 if (single) { 1886 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1887 (bits(machInst, 22))); 1888 } else { 1889 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1890 (bits(machInst, 22) << 5)); 1891 } 1892 if (bits(opcode, 1, 0) == 0x0) { 1893 if (single) { 1894 if (up) { 1895 return new %(vstr_us)s(machInst, vd, rn, up, imm); 1896 } else { 1897 return new %(vstr_s)s(machInst, vd, rn, up, imm); 1898 } 1899 } else { 1900 if (up) { 1901 return new %(vstr_ud)s(machInst, vd, vd + 1, 1902 rn, up, imm); 1903 } else { 1904 return new %(vstr_d)s(machInst, vd, vd + 1, 1905 rn, up, imm); 1906 } 1907 } 1908 } else if (bits(opcode, 1, 0) == 0x1) { 1909 if (single) { 1910 if (up) { 1911 return new %(vldr_us)s(machInst, vd, rn, up, imm); 1912 } else { 1913 return new %(vldr_s)s(machInst, vd, rn, up, imm); 1914 } 1915 } else { 1916 if (up) { 1917 return new %(vldr_ud)s(machInst, vd, vd + 1, 1918 rn, up, imm); 1919 } else { 1920 return new %(vldr_d)s(machInst, vd, vd + 1, 1921 rn, up, imm); 1922 } 1923 } 1924 } 1925 } 1926 return new Unknown(machInst); 1927 } 1928 ''' % { 1929 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 1930 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 1931 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 1932 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 1933 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 1934 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 1935 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 1936 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 1937 } 1938}}; 1939 1940def format ExtensionRegLoadStore() {{ 1941 decode_block = ''' 1942 return decodeExtensionRegLoadStore(machInst); 1943 ''' 1944}}; 1945 1946let {{ 1947 header_output = ''' 1948 StaticInstPtr 1949 decodeShortFpTransfer(ExtMachInst machInst); 1950 ''' 1951 decoder_output = ''' 1952 StaticInstPtr 1953 decodeShortFpTransfer(ExtMachInst machInst) 1954 { 1955 const uint32_t l = bits(machInst, 20); 1956 const uint32_t c = bits(machInst, 8); 1957 const uint32_t a = bits(machInst, 23, 21); 1958 const uint32_t b = bits(machInst, 6, 5); 1959 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 1960 (machInst.thumb == 0 && machInst.condCode == 0xf)) { 1961 // Determine if this is backported aarch64 FP instruction 1962 const bool b31_b24 = bits(machInst, 31, 24) == 0xFE; 1963 const bool b23 = bits(machInst, 23); 1964 const bool b21_b18 = bits(machInst, 21, 18) == 0xE; 1965 const bool b11_b9 = bits(machInst, 11, 9) == 0x5; 1966 const bool sz = bits(machInst, 8); 1967 const bool b7_b6 = bits(machInst, 7, 6) == 0x1; 1968 const bool b6 = bits(machInst, 6) == 0x0; 1969 const bool b4 = bits(machInst, 4) == 0x0; 1970 if (b31_b24 && b23 && b21_b18 && b11_b9 && b7_b6 && b4) { 1971 // VINT* Integer Rounding Instructon 1972 const uint32_t rm = bits(machInst, 17, 16); 1973 1974 if (sz) { 1975 const IntRegIndex vd = 1976 (IntRegIndex)((bits(machInst, 22) << 5) | 1977 (bits(machInst, 15, 12) << 1)); 1978 const IntRegIndex vm = 1979 (IntRegIndex)((bits(machInst, 5) << 5) | 1980 (bits(machInst, 3, 0) << 1)); 1981 switch(rm) { 1982 case 0x0: 1983 return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm, 1984 true); 1985 case 0x1: 1986 return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm, 1987 true); 1988 case 0x2: 1989 return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm, 1990 true); 1991 case 0x3: 1992 return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm, 1993 true); 1994 default: return new Unknown(machInst); 1995 } 1996 } else { 1997 const IntRegIndex vd = 1998 (IntRegIndex)(bits(machInst, 22) | 1999 (bits(machInst, 15, 12) << 1)); 2000 const IntRegIndex vm = 2001 (IntRegIndex)(bits(machInst, 5) | 2002 (bits(machInst, 3, 0) << 1)); 2003 switch(rm) { 2004 case 0x0: 2005 return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm, 2006 false); 2007 case 0x1: 2008 return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm, 2009 false); 2010 case 0x2: 2011 return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm, 2012 false); 2013 case 0x3: 2014 return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm, 2015 false); 2016 default: return new Unknown(machInst); 2017 } 2018 } 2019 } else if (b31_b24 && !b23 && b11_b9 && b6 && b4){ 2020 // VSEL* floating point conditional select 2021 2022 ConditionCode cond; 2023 switch(bits(machInst, 21, 20)) { 2024 case 0x0: cond = COND_EQ; break; 2025 case 0x1: cond = COND_VS; break; 2026 case 0x2: cond = COND_GE; break; 2027 case 0x3: cond = COND_GT; break; 2028 } 2029 2030 if (sz) { 2031 const IntRegIndex vd = 2032 (IntRegIndex)((bits(machInst, 22) << 5) | 2033 (bits(machInst, 15, 12) << 1)); 2034 const IntRegIndex vm = 2035 (IntRegIndex)((bits(machInst, 5) << 5) | 2036 (bits(machInst, 3, 0) << 1)); 2037 const IntRegIndex vn = 2038 (IntRegIndex)((bits(machInst, 7) << 5) | 2039 (bits(machInst, 19, 16) << 1)); 2040 return new VselD(machInst, vd, vn, vm, cond); 2041 } else { 2042 const IntRegIndex vd = 2043 (IntRegIndex)(bits(machInst, 22) | 2044 (bits(machInst, 15, 12) << 1)); 2045 const IntRegIndex vm = 2046 (IntRegIndex)(bits(machInst, 5) | 2047 (bits(machInst, 3, 0) << 1)); 2048 const IntRegIndex vn = 2049 (IntRegIndex)((bits(machInst, 19, 16) << 1) | 2050 bits(machInst, 7)); 2051 return new VselS(machInst, vd, vn, vm, cond); 2052 } 2053 } else { 2054 return new Unknown(machInst); 2055 } 2056 } 2057 if (l == 0 && c == 0) { 2058 if (a == 0) { 2059 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2060 bits(machInst, 7); 2061 const IntRegIndex rt = 2062 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2063 if (bits(machInst, 20) == 1) { 2064 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2065 } else { 2066 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2067 } 2068 } else if (a == 0x7) { 2069 const IntRegIndex rt = 2070 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2071 uint32_t reg = bits(machInst, 19, 16); 2072 uint32_t specReg; 2073 switch (reg) { 2074 case 0: 2075 specReg = MISCREG_FPSID; 2076 break; 2077 case 1: 2078 specReg = MISCREG_FPSCR; 2079 break; 2080 case 6: 2081 specReg = MISCREG_MVFR1; 2082 break; 2083 case 7: 2084 specReg = MISCREG_MVFR0; 2085 break; 2086 case 8: 2087 specReg = MISCREG_FPEXC; 2088 break; 2089 default: 2090 return new Unknown(machInst); 2091 } 2092 if (specReg == MISCREG_FPSCR) { 2093 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 2094 } else { 2095 uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt, 2096 reg, a, bits(machInst, 7, 5)); 2097 return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss); 2098 } 2099 } 2100 } else if (l == 0 && c == 1) { 2101 if (bits(a, 2) == 0) { 2102 uint32_t vd = (bits(machInst, 7) << 5) | 2103 (bits(machInst, 19, 16) << 1); 2104 // Handle accessing each single precision half of the vector. 2105 vd += bits(machInst, 21); 2106 const IntRegIndex rt = 2107 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2108 if (bits(machInst, 22) == 1) { 2109 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 2110 rt, bits(machInst, 6, 5)); 2111 } else if (bits(machInst, 5) == 1) { 2112 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 2113 rt, bits(machInst, 6)); 2114 } else if (bits(machInst, 6) == 0) { 2115 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 2116 } else { 2117 return new Unknown(machInst); 2118 } 2119 } else if (bits(b, 1) == 0) { 2120 bool q = bits(machInst, 21); 2121 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2122 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2123 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2124 IntRegIndex rt = (IntRegIndex)(uint32_t) 2125 bits(machInst, 15, 12); 2126 if (q) { 2127 switch (be) { 2128 case 0: 2129 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2130 case 1: 2131 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2132 case 2: 2133 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2134 case 3: 2135 return new Unknown(machInst); 2136 } 2137 } else { 2138 switch (be) { 2139 case 0: 2140 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2141 case 1: 2142 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2143 case 2: 2144 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2145 case 3: 2146 return new Unknown(machInst); 2147 } 2148 } 2149 } 2150 } else if (l == 1 && c == 0) { 2151 if (a == 0) { 2152 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2153 bits(machInst, 7); 2154 const IntRegIndex rt = 2155 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2156 if (bits(machInst, 20) == 1) { 2157 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2158 } else { 2159 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2160 } 2161 } else if (a == 7) { 2162 const IntRegIndex rt = 2163 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2164 uint32_t reg = bits(machInst, 19, 16); 2165 uint32_t specReg; 2166 switch (reg) { 2167 case 0: 2168 specReg = MISCREG_FPSID; 2169 break; 2170 case 1: 2171 specReg = MISCREG_FPSCR; 2172 break; 2173 case 6: 2174 specReg = MISCREG_MVFR1; 2175 break; 2176 case 7: 2177 specReg = MISCREG_MVFR0; 2178 break; 2179 case 8: 2180 specReg = MISCREG_FPEXC; 2181 break; 2182 default: 2183 return new Unknown(machInst); 2184 } 2185 if (rt == 0xf) { 2186 if (specReg == MISCREG_FPSCR) { 2187 return new VmrsApsrFpscr(machInst); 2188 } else { 2189 return new Unknown(machInst); 2190 } 2191 } else if (specReg == MISCREG_FPSCR) { 2192 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2193 } else { 2194 uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt, 2195 reg, a, bits(machInst, 7, 5)); 2196 return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss); 2197 } 2198 } 2199 } else { 2200 uint32_t vd = (bits(machInst, 7) << 5) | 2201 (bits(machInst, 19, 16) << 1); 2202 // Handle indexing into each single precision half of the vector. 2203 vd += bits(machInst, 21); 2204 uint32_t index; 2205 const IntRegIndex rt = 2206 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2207 const bool u = (bits(machInst, 23) == 1); 2208 if (bits(machInst, 22) == 1) { 2209 index = bits(machInst, 6, 5); 2210 if (u) { 2211 return new VmovRegCoreUB(machInst, rt, 2212 (IntRegIndex)vd, index); 2213 } else { 2214 return new VmovRegCoreSB(machInst, rt, 2215 (IntRegIndex)vd, index); 2216 } 2217 } else if (bits(machInst, 5) == 1) { 2218 index = bits(machInst, 6); 2219 if (u) { 2220 return new VmovRegCoreUH(machInst, rt, 2221 (IntRegIndex)vd, index); 2222 } else { 2223 return new VmovRegCoreSH(machInst, rt, 2224 (IntRegIndex)vd, index); 2225 } 2226 } else if (bits(machInst, 6) == 0 && !u) { 2227 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2228 } else { 2229 return new Unknown(machInst); 2230 } 2231 } 2232 return new Unknown(machInst); 2233 } 2234 ''' 2235}}; 2236 2237def format ShortFpTransfer() {{ 2238 decode_block = ''' 2239 return decodeShortFpTransfer(machInst); 2240 ''' 2241}}; 2242 2243let {{ 2244 header_output = ''' 2245 StaticInstPtr 2246 decodeVfpData(ExtMachInst machInst); 2247 ''' 2248 decoder_output = ''' 2249 StaticInstPtr 2250 decodeVfpData(ExtMachInst machInst) 2251 { 2252 const uint32_t opc1 = bits(machInst, 23, 20); 2253 const uint32_t opc2 = bits(machInst, 19, 16); 2254 const uint32_t opc3 = bits(machInst, 7, 6); 2255 //const uint32_t opc4 = bits(machInst, 3, 0); 2256 const bool single = (bits(machInst, 8) == 0); 2257 // Used to select between vcmp and vcmpe. 2258 const bool e = (bits(machInst, 7) == 1); 2259 IntRegIndex vd; 2260 IntRegIndex vm; 2261 IntRegIndex vn; 2262 if (single) { 2263 vd = (IntRegIndex)(bits(machInst, 22) | 2264 (bits(machInst, 15, 12) << 1)); 2265 vm = (IntRegIndex)(bits(machInst, 5) | 2266 (bits(machInst, 3, 0) << 1)); 2267 vn = (IntRegIndex)(bits(machInst, 7) | 2268 (bits(machInst, 19, 16) << 1)); 2269 } else { 2270 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2271 (bits(machInst, 15, 12) << 1)); 2272 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2273 (bits(machInst, 3, 0) << 1)); 2274 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2275 (bits(machInst, 19, 16) << 1)); 2276 } 2277 switch (opc1 & 0xb /* 1011 */) { 2278 case 0x0: 2279 if (bits(machInst, 6) == 0) { 2280 if (single) { 2281 return decodeVfpRegRegRegOp<VmlaS>( 2282 machInst, vd, vn, vm, false); 2283 } else { 2284 return decodeVfpRegRegRegOp<VmlaD>( 2285 machInst, vd, vn, vm, true); 2286 } 2287 } else { 2288 if (single) { 2289 return decodeVfpRegRegRegOp<VmlsS>( 2290 machInst, vd, vn, vm, false); 2291 } else { 2292 return decodeVfpRegRegRegOp<VmlsD>( 2293 machInst, vd, vn, vm, true); 2294 } 2295 } 2296 case 0x1: 2297 if (bits(machInst, 6) == 1) { 2298 if (single) { 2299 return decodeVfpRegRegRegOp<VnmlaS>( 2300 machInst, vd, vn, vm, false); 2301 } else { 2302 return decodeVfpRegRegRegOp<VnmlaD>( 2303 machInst, vd, vn, vm, true); 2304 } 2305 } else { 2306 if (single) { 2307 return decodeVfpRegRegRegOp<VnmlsS>( 2308 machInst, vd, vn, vm, false); 2309 } else { 2310 return decodeVfpRegRegRegOp<VnmlsD>( 2311 machInst, vd, vn, vm, true); 2312 } 2313 } 2314 case 0x2: 2315 if ((opc3 & 0x1) == 0) { 2316 if (single) { 2317 return decodeVfpRegRegRegOp<VmulS>( 2318 machInst, vd, vn, vm, false); 2319 } else { 2320 return decodeVfpRegRegRegOp<VmulD>( 2321 machInst, vd, vn, vm, true); 2322 } 2323 } else { 2324 if (single) { 2325 return decodeVfpRegRegRegOp<VnmulS>( 2326 machInst, vd, vn, vm, false); 2327 } else { 2328 return decodeVfpRegRegRegOp<VnmulD>( 2329 machInst, vd, vn, vm, true); 2330 } 2331 } 2332 case 0x3: 2333 if ((opc3 & 0x1) == 0) { 2334 if (single) { 2335 return decodeVfpRegRegRegOp<VaddS>( 2336 machInst, vd, vn, vm, false); 2337 } else { 2338 return decodeVfpRegRegRegOp<VaddD>( 2339 machInst, vd, vn, vm, true); 2340 } 2341 } else { 2342 if (single) { 2343 return decodeVfpRegRegRegOp<VsubS>( 2344 machInst, vd, vn, vm, false); 2345 } else { 2346 return decodeVfpRegRegRegOp<VsubD>( 2347 machInst, vd, vn, vm, true); 2348 } 2349 } 2350 case 0x8: 2351 if ((opc3 & 0x1) == 0) { 2352 if (single) { 2353 return decodeVfpRegRegRegOp<VdivS>( 2354 machInst, vd, vn, vm, false); 2355 } else { 2356 return decodeVfpRegRegRegOp<VdivD>( 2357 machInst, vd, vn, vm, true); 2358 } 2359 } 2360 break; 2361 case 0x9: 2362 if ((opc3 & 0x1) == 0) { 2363 if (single) { 2364 return decodeVfpRegRegRegOp<VfnmaS>( 2365 machInst, vd, vn, vm, false); 2366 } else { 2367 return decodeVfpRegRegRegOp<VfnmaD>( 2368 machInst, vd, vn, vm, true); 2369 } 2370 } else { 2371 if (single) { 2372 return decodeVfpRegRegRegOp<VfnmsS>( 2373 machInst, vd, vn, vm, false); 2374 } else { 2375 return decodeVfpRegRegRegOp<VfnmsD>( 2376 machInst, vd, vn, vm, true); 2377 } 2378 } 2379 break; 2380 case 0xa: 2381 if ((opc3 & 0x1) == 0) { 2382 if (single) { 2383 return decodeVfpRegRegRegOp<VfmaS>( 2384 machInst, vd, vn, vm, false); 2385 } else { 2386 return decodeVfpRegRegRegOp<VfmaD>( 2387 machInst, vd, vn, vm, true); 2388 } 2389 } else { 2390 if (single) { 2391 return decodeVfpRegRegRegOp<VfmsS>( 2392 machInst, vd, vn, vm, false); 2393 } else { 2394 return decodeVfpRegRegRegOp<VfmsD>( 2395 machInst, vd, vn, vm, true); 2396 } 2397 } 2398 break; 2399 case 0xb: 2400 if ((opc3 & 0x1) == 0) { 2401 const uint32_t baseImm = 2402 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2403 if (single) { 2404 uint32_t imm = vfp_modified_imm(baseImm, false); 2405 return decodeVfpRegImmOp<VmovImmS>( 2406 machInst, vd, imm, false); 2407 } else { 2408 uint64_t imm = vfp_modified_imm(baseImm, true); 2409 return decodeVfpRegImmOp<VmovImmD>( 2410 machInst, vd, imm, true); 2411 } 2412 } 2413 switch (opc2) { 2414 case 0x0: 2415 if (opc3 == 1) { 2416 if (single) { 2417 return decodeVfpRegRegOp<VmovRegS>( 2418 machInst, vd, vm, false); 2419 } else { 2420 return decodeVfpRegRegOp<VmovRegD>( 2421 machInst, vd, vm, true); 2422 } 2423 } else { 2424 if (single) { 2425 return decodeVfpRegRegOp<VabsS>( 2426 machInst, vd, vm, false); 2427 } else { 2428 return decodeVfpRegRegOp<VabsD>( 2429 machInst, vd, vm, true); 2430 } 2431 } 2432 case 0x1: 2433 if (opc3 == 1) { 2434 if (single) { 2435 return decodeVfpRegRegOp<VnegS>( 2436 machInst, vd, vm, false); 2437 } else { 2438 return decodeVfpRegRegOp<VnegD>( 2439 machInst, vd, vm, true); 2440 } 2441 } else { 2442 if (single) { 2443 return decodeVfpRegRegOp<VsqrtS>( 2444 machInst, vd, vm, false); 2445 } else { 2446 return decodeVfpRegRegOp<VsqrtD>( 2447 machInst, vd, vm, true); 2448 } 2449 } 2450 case 0x2: 2451 case 0x3: 2452 { 2453 const bool toHalf = bits(machInst, 16); 2454 const bool top = bits(machInst, 7); 2455 if (top) { 2456 if (toHalf) { 2457 return new VcvtFpSFpHT(machInst, vd, vm); 2458 } else { 2459 return new VcvtFpHTFpS(machInst, vd, vm); 2460 } 2461 } else { 2462 if (toHalf) { 2463 return new VcvtFpSFpHB(machInst, vd, vm); 2464 } else { 2465 return new VcvtFpHBFpS(machInst, vd, vm); 2466 } 2467 } 2468 } 2469 case 0x4: 2470 if (single) { 2471 if (e) { 2472 return new VcmpeS(machInst, vd, vm); 2473 } else { 2474 return new VcmpS(machInst, vd, vm); 2475 } 2476 } else { 2477 if (e) { 2478 return new VcmpeD(machInst, vd, vm); 2479 } else { 2480 return new VcmpD(machInst, vd, vm); 2481 } 2482 } 2483 case 0x5: 2484 if (single) { 2485 if (e) { 2486 return new VcmpeZeroS(machInst, vd, 0); 2487 } else { 2488 return new VcmpZeroS(machInst, vd, 0); 2489 } 2490 } else { 2491 if (e) { 2492 return new VcmpeZeroD(machInst, vd, 0); 2493 } else { 2494 return new VcmpZeroD(machInst, vd, 0); 2495 } 2496 } 2497 case 0x7: 2498 if (opc3 == 0x3) { 2499 if (single) { 2500 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2501 (bits(machInst, 15, 12) << 1)); 2502 return new VcvtFpSFpD(machInst, vd, vm); 2503 } else { 2504 vd = (IntRegIndex)(bits(machInst, 22) | 2505 (bits(machInst, 15, 12) << 1)); 2506 return new VcvtFpDFpS(machInst, vd, vm); 2507 } 2508 } 2509 break; 2510 case 0x8: 2511 if (bits(machInst, 7) == 0) { 2512 if (single) { 2513 return new VcvtUIntFpS(machInst, vd, vm); 2514 } else { 2515 vm = (IntRegIndex)(bits(machInst, 5) | 2516 (bits(machInst, 3, 0) << 1)); 2517 return new VcvtUIntFpD(machInst, vd, vm); 2518 } 2519 } else { 2520 if (single) { 2521 return new VcvtSIntFpS(machInst, vd, vm); 2522 } else { 2523 vm = (IntRegIndex)(bits(machInst, 5) | 2524 (bits(machInst, 3, 0) << 1)); 2525 return new VcvtSIntFpD(machInst, vd, vm); 2526 } 2527 } 2528 case 0xa: 2529 { 2530 const bool half = (bits(machInst, 7) == 0); 2531 const uint32_t imm = bits(machInst, 5) | 2532 (bits(machInst, 3, 0) << 1); 2533 const uint32_t size = 2534 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2535 if (single) { 2536 if (half) { 2537 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2538 } else { 2539 return new VcvtSFixedFpS(machInst, vd, vd, size); 2540 } 2541 } else { 2542 if (half) { 2543 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2544 } else { 2545 return new VcvtSFixedFpD(machInst, vd, vd, size); 2546 } 2547 } 2548 } 2549 case 0xb: 2550 { 2551 const bool half = (bits(machInst, 7) == 0); 2552 const uint32_t imm = bits(machInst, 5) | 2553 (bits(machInst, 3, 0) << 1); 2554 const uint32_t size = 2555 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2556 if (single) { 2557 if (half) { 2558 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2559 } else { 2560 return new VcvtUFixedFpS(machInst, vd, vd, size); 2561 } 2562 } else { 2563 if (half) { 2564 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2565 } else { 2566 return new VcvtUFixedFpD(machInst, vd, vd, size); 2567 } 2568 } 2569 } 2570 case 0xc: 2571 if (bits(machInst, 7) == 0) { 2572 if (single) { 2573 return new VcvtFpUIntSR(machInst, vd, vm); 2574 } else { 2575 vd = (IntRegIndex)(bits(machInst, 22) | 2576 (bits(machInst, 15, 12) << 1)); 2577 return new VcvtFpUIntDR(machInst, vd, vm); 2578 } 2579 } else { 2580 if (single) { 2581 return new VcvtFpUIntS(machInst, vd, vm); 2582 } else { 2583 vd = (IntRegIndex)(bits(machInst, 22) | 2584 (bits(machInst, 15, 12) << 1)); 2585 return new VcvtFpUIntD(machInst, vd, vm); 2586 } 2587 } 2588 case 0xd: 2589 if (bits(machInst, 7) == 0) { 2590 if (single) { 2591 return new VcvtFpSIntSR(machInst, vd, vm); 2592 } else { 2593 vd = (IntRegIndex)(bits(machInst, 22) | 2594 (bits(machInst, 15, 12) << 1)); 2595 return new VcvtFpSIntDR(machInst, vd, vm); 2596 } 2597 } else { 2598 if (single) { 2599 return new VcvtFpSIntS(machInst, vd, vm); 2600 } else { 2601 vd = (IntRegIndex)(bits(machInst, 22) | 2602 (bits(machInst, 15, 12) << 1)); 2603 return new VcvtFpSIntD(machInst, vd, vm); 2604 } 2605 } 2606 case 0xe: 2607 { 2608 const bool half = (bits(machInst, 7) == 0); 2609 const uint32_t imm = bits(machInst, 5) | 2610 (bits(machInst, 3, 0) << 1); 2611 const uint32_t size = 2612 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2613 if (single) { 2614 if (half) { 2615 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2616 } else { 2617 return new VcvtFpSFixedS(machInst, vd, vd, size); 2618 } 2619 } else { 2620 if (half) { 2621 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2622 } else { 2623 return new VcvtFpSFixedD(machInst, vd, vd, size); 2624 } 2625 } 2626 } 2627 case 0xf: 2628 { 2629 const bool half = (bits(machInst, 7) == 0); 2630 const uint32_t imm = bits(machInst, 5) | 2631 (bits(machInst, 3, 0) << 1); 2632 const uint32_t size = 2633 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2634 if (single) { 2635 if (half) { 2636 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2637 } else { 2638 return new VcvtFpUFixedS(machInst, vd, vd, size); 2639 } 2640 } else { 2641 if (half) { 2642 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2643 } else { 2644 return new VcvtFpUFixedD(machInst, vd, vd, size); 2645 } 2646 } 2647 } 2648 } 2649 break; 2650 } 2651 return new Unknown(machInst); 2652 } 2653 ''' 2654}}; 2655 2656def format VfpData() {{ 2657 decode_block = ''' 2658 return decodeVfpData(machInst); 2659 ''' 2660}}; 2661