fp.isa revision 7643
19814Sandreas.hansson@arm.com// -*- mode:c++ -*- 22292SN/A 312216Snikos.nikoleris@arm.com// Copyright (c) 2010 ARM Limited 410239Sbinhpham@cs.rutgers.edu// All rights reserved 57597Sminkyu.jeong@arm.com// 67597Sminkyu.jeong@arm.com// The license below extends only to copyright in the software and shall 77597Sminkyu.jeong@arm.com// not be construed as granting a license to any other intellectual 87597Sminkyu.jeong@arm.com// property including but not limited to intellectual property relating 97597Sminkyu.jeong@arm.com// to a hardware implementation of the functionality of the software 107597Sminkyu.jeong@arm.com// licensed hereunder. You may use the software subject to the license 117597Sminkyu.jeong@arm.com// terms below provided that you ensure that this notice is replicated 127597Sminkyu.jeong@arm.com// unmodified and in its entirety in all distributions of the software, 137597Sminkyu.jeong@arm.com// modified or unmodified, in source code or in binary form. 147597Sminkyu.jeong@arm.com// 157597Sminkyu.jeong@arm.com// Copyright (c) 2007-2008 The Florida State University 162292SN/A// All rights reserved. 172292SN/A// 182292SN/A// Redistribution and use in source and binary forms, with or without 192292SN/A// modification, are permitted provided that the following conditions are 202292SN/A// met: redistributions of source code must retain the above copyright 212292SN/A// notice, this list of conditions and the following disclaimer; 222292SN/A// redistributions in binary form must reproduce the above copyright 232292SN/A// notice, this list of conditions and the following disclaimer in the 242292SN/A// documentation and/or other materials provided with the distribution; 252292SN/A// neither the name of the copyright holders nor the names of its 262292SN/A// contributors may be used to endorse or promote products derived from 272292SN/A// this software without specific prior written permission. 282292SN/A// 292292SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302292SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312292SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322292SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332292SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342292SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352292SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362292SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372292SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382292SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392292SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402292SN/A// 412689Sktlim@umich.edu// Authors: Stephen Hines 422689Sktlim@umich.edu 432689Sktlim@umich.edu//////////////////////////////////////////////////////////////////// 442292SN/A// 452292SN/A// Floating Point operate instructions 469944Smatt.horsnell@ARM.com// 479944Smatt.horsnell@ARM.com 489944Smatt.horsnell@ARM.comoutput header {{ 498591Sgblack@eecs.umich.edu 503326Sktlim@umich.edu template<template <typename T> class Base> 518229Snate@binkert.org StaticInstPtr 526658Snate@binkert.org newNeonMemInst(const unsigned size, 538887Sgeoffrey.blake@arm.com const ExtMachInst &machInst, 542907Sktlim@umich.edu const RegIndex dest, const RegIndex ra, 552292SN/A const uint32_t imm, const unsigned extraMemFlags) 568232Snate@binkert.org { 578232Snate@binkert.org switch (size) { 588232Snate@binkert.org case 0: 599527SMatt.Horsnell@arm.com return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags); 602722Sktlim@umich.edu case 1: 612669Sktlim@umich.edu return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags); 622292SN/A case 2: 632669Sktlim@umich.edu return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags); 642678Sktlim@umich.edu case 3: 652678Sktlim@umich.edu return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags); 668581Ssteve.reinhardt@amd.com default: 678581Ssteve.reinhardt@amd.com panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 682292SN/A } 692292SN/A } 702292SN/A 712669Sktlim@umich.edu template<template <typename T> class Base> 722292SN/A StaticInstPtr 732678Sktlim@umich.edu newNeonMixInst(const unsigned size, 742292SN/A const ExtMachInst &machInst, 759444SAndreas.Sandberg@ARM.com const RegIndex dest, const RegIndex op1, 769444SAndreas.Sandberg@ARM.com const uint32_t step) 779444SAndreas.Sandberg@ARM.com { 784319Sktlim@umich.edu switch (size) { 794319Sktlim@umich.edu case 0: 804319Sktlim@umich.edu return new Base<uint8_t>(machInst, dest, op1, step); 814319Sktlim@umich.edu case 1: 822678Sktlim@umich.edu return new Base<uint16_t>(machInst, dest, op1, step); 832678Sktlim@umich.edu case 2: 842292SN/A return new Base<uint32_t>(machInst, dest, op1, step); 852678Sktlim@umich.edu case 3: 862678Sktlim@umich.edu return new Base<uint64_t>(machInst, dest, op1, step); 875336Shines@cs.fsu.edu default: 882678Sktlim@umich.edu panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 894873Sstever@eecs.umich.edu } 902678Sktlim@umich.edu } 912292SN/A 922678Sktlim@umich.edu}}; 932678Sktlim@umich.edu 942678Sktlim@umich.edulet {{ 952678Sktlim@umich.edu header_output = ''' 962678Sktlim@umich.edu StaticInstPtr 972678Sktlim@umich.edu decodeNeonMem(ExtMachInst machInst); 987852SMatt.Horsnell@arm.com 997852SMatt.Horsnell@arm.com StaticInstPtr 1002344SN/A decodeNeonData(ExtMachInst machInst); 10110333Smitch.hayenga@arm.com ''' 10210333Smitch.hayenga@arm.com 10310333Smitch.hayenga@arm.com decoder_output = ''' 10410333Smitch.hayenga@arm.com StaticInstPtr 10510333Smitch.hayenga@arm.com decodeNeonMem(ExtMachInst machInst) 10610333Smitch.hayenga@arm.com { 10710333Smitch.hayenga@arm.com const uint32_t b = bits(machInst, 11, 8); 10810333Smitch.hayenga@arm.com const bool single = bits(machInst, 23); 1092678Sktlim@umich.edu const bool singleAll = single && (bits(b, 3, 2) == 3); 1106974Stjones1@inf.ed.ac.uk const bool load = bits(machInst, 21); 1116974Stjones1@inf.ed.ac.uk 1126974Stjones1@inf.ed.ac.uk unsigned width = 0; 1136974Stjones1@inf.ed.ac.uk 1146974Stjones1@inf.ed.ac.uk if (single) { 1159444SAndreas.Sandberg@ARM.com width = bits(b, 1, 0) + 1; 11610327Smitch.hayenga@arm.com } else { 1172678Sktlim@umich.edu switch (bits(b, 3, 1)) { 11812216Snikos.nikoleris@arm.com case 0x0: width = 4; 11912216Snikos.nikoleris@arm.com break; 12012216Snikos.nikoleris@arm.com case 0x1: width = (b & 0x1) ? 2 : 1; 1216974Stjones1@inf.ed.ac.uk break; 1226974Stjones1@inf.ed.ac.uk case 0x2: width = 3; 1236974Stjones1@inf.ed.ac.uk break; 1246974Stjones1@inf.ed.ac.uk case 0x3: width = 1; 1256974Stjones1@inf.ed.ac.uk break; 1266974Stjones1@inf.ed.ac.uk case 0x4: width = 2; 1272678Sktlim@umich.edu break; 1282678Sktlim@umich.edu case 0x5: 1292678Sktlim@umich.edu if ((b & 0x1) == 0) { 1302678Sktlim@umich.edu width = 1; 1312678Sktlim@umich.edu break; 1322344SN/A } 1332307SN/A // Fall through on purpose. 1346974Stjones1@inf.ed.ac.uk default: 1356974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 1366974Stjones1@inf.ed.ac.uk } 13710020Smatt.horsnell@ARM.com } 13810020Smatt.horsnell@ARM.com assert(width > 0 && width <= 4); 13910023Smatt.horsnell@ARM.com 14010023Smatt.horsnell@ARM.com const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0); 1412678Sktlim@umich.edu const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16); 1422292SN/A const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) | 1432292SN/A bits(machInst, 22) << 4); 1442292SN/A const uint32_t type = bits(machInst, 11, 8); 1452292SN/A uint32_t size = 0; 1468545Ssaidi@eecs.umich.edu uint32_t align = 0; 14711243Spau.cabre@metempsy.com unsigned inc = 1; 14811243Spau.cabre@metempsy.com unsigned regs = 1; 1492292SN/A unsigned lane = 0; 1502292SN/A if (single) { 1512292SN/A if (singleAll) { 1522292SN/A size = bits(machInst, 7, 6); 1532292SN/A bool t = bits(machInst, 5); 1545529Snate@binkert.org unsigned eBytes = (1 << size); 1555529Snate@binkert.org align = (eBytes - 1) | TLB::AllowUnaligned; 1565529Snate@binkert.org if (width == 1) { 1572292SN/A regs = t ? 2 : 1; 1584329Sktlim@umich.edu inc = 1; 1594329Sktlim@umich.edu } else { 1604329Sktlim@umich.edu regs = width; 1612907Sktlim@umich.edu inc = t ? 2 : 1; 1622907Sktlim@umich.edu } 1632292SN/A switch (width) { 1642292SN/A case 1: 16510175SMitch.Hayenga@ARM.com case 2: 16610175SMitch.Hayenga@ARM.com if (bits(machInst, 4)) 1672329SN/A align = width * eBytes - 1; 1682329SN/A break; 1692329SN/A case 3: 1702292SN/A break; 1719936SFaissal.Sleiman@arm.com case 4: 1729936SFaissal.Sleiman@arm.com if (size == 3) { 1739936SFaissal.Sleiman@arm.com if (bits(machInst, 4) == 0) 1749936SFaissal.Sleiman@arm.com return new Unknown(machInst); 1752292SN/A size = 2; 1762292SN/A align = 0xf; 1772292SN/A } else if (size == 2) { 1788199SAli.Saidi@ARM.com if (bits(machInst, 4)) 1798199SAli.Saidi@ARM.com align = 7; 18011780Sarthur.perais@inria.fr } else { 1819444SAndreas.Sandberg@ARM.com if (bits(machInst, 4)) 1829444SAndreas.Sandberg@ARM.com align = 4 * eBytes - 1; 1839444SAndreas.Sandberg@ARM.com } 1849444SAndreas.Sandberg@ARM.com break; 1859444SAndreas.Sandberg@ARM.com } 1869444SAndreas.Sandberg@ARM.com } else { 1879444SAndreas.Sandberg@ARM.com size = bits(machInst, 11, 10); 1889444SAndreas.Sandberg@ARM.com unsigned eBytes = (1 << size); 1899444SAndreas.Sandberg@ARM.com align = (eBytes - 1) | TLB::AllowUnaligned; 1909444SAndreas.Sandberg@ARM.com regs = width; 1919444SAndreas.Sandberg@ARM.com unsigned indexAlign = bits(machInst, 7, 4); 1928199SAli.Saidi@ARM.com // If width is 1, inc is always 1. That's overridden later. 1932292SN/A switch (size) { 1942292SN/A case 0: 1952292SN/A inc = 1; 1962292SN/A lane = bits(indexAlign, 3, 1); 19711780Sarthur.perais@inria.fr break; 1982292SN/A case 1: 1993492Sktlim@umich.edu inc = bits(indexAlign, 1) ? 2 : 1; 2002329SN/A lane = bits(indexAlign, 3, 2); 2012292SN/A break; 2029444SAndreas.Sandberg@ARM.com case 2: 2039444SAndreas.Sandberg@ARM.com inc = bits(indexAlign, 2) ? 2 : 1; 2049814Sandreas.hansson@arm.com lane = bits(indexAlign, 3); 2052292SN/A break; 2062292SN/A } 2072292SN/A // Override inc for width of 1. 2082292SN/A if (width == 1) { 2092292SN/A inc = 1; 2102292SN/A } 2112292SN/A switch (width) { 2122292SN/A case 1: 2132292SN/A switch (size) { 21410386Sandreas.hansson@arm.com case 0: 2152292SN/A break; 2162292SN/A case 1: 2172292SN/A if (bits(indexAlign, 0)) 2182292SN/A align = 1; 2192292SN/A break; 2202727Sktlim@umich.edu case 2: 2212727Sktlim@umich.edu if (bits(indexAlign, 1, 0)) 2222727Sktlim@umich.edu align = 3; 2232727Sktlim@umich.edu break; 2242727Sktlim@umich.edu } 2252727Sktlim@umich.edu break; 2262727Sktlim@umich.edu case 2: 2272727Sktlim@umich.edu if (bits(indexAlign, 0)) 2282727Sktlim@umich.edu align = (2 * eBytes) - 1; 2292727Sktlim@umich.edu break; 2302727Sktlim@umich.edu case 3: 2312727Sktlim@umich.edu break; 2322727Sktlim@umich.edu case 4: 2332727Sktlim@umich.edu switch (size) { 2342727Sktlim@umich.edu case 0: 2352727Sktlim@umich.edu case 1: 2362727Sktlim@umich.edu if (bits(indexAlign, 0)) 2372727Sktlim@umich.edu align = (4 * eBytes) - 1; 2382361SN/A break; 2392361SN/A case 2: 2402361SN/A if (bits(indexAlign, 0)) 2412361SN/A align = (4 << bits(indexAlign, 1, 0)) - 1; 2422727Sktlim@umich.edu break; 2432727Sktlim@umich.edu } 2442727Sktlim@umich.edu break; 2452727Sktlim@umich.edu } 2462727Sktlim@umich.edu } 2472727Sktlim@umich.edu if (size == 0x3) { 2482727Sktlim@umich.edu return new Unknown(machInst); 2492727Sktlim@umich.edu } 2502727Sktlim@umich.edu } else { 2512727Sktlim@umich.edu size = bits(machInst, 7, 6); 2522727Sktlim@umich.edu align = bits(machInst, 5, 4); 2532727Sktlim@umich.edu if (align == 0) { 2542727Sktlim@umich.edu // @align wasn't specified, so alignment can be turned off. 2552727Sktlim@umich.edu align = ((1 << size) - 1) | TLB::AllowUnaligned; 2562727Sktlim@umich.edu } else { 2572727Sktlim@umich.edu align = ((4 << align) - 1); 2582727Sktlim@umich.edu } 2592727Sktlim@umich.edu switch (width) { 2602727Sktlim@umich.edu case 1: 2612727Sktlim@umich.edu switch (type) { 2622727Sktlim@umich.edu case 0x7: regs = 1; 2632727Sktlim@umich.edu break; 2642727Sktlim@umich.edu case 0xa: regs = 2; 2658922Swilliam.wang@arm.com break; 2664329Sktlim@umich.edu case 0x6: regs = 3; 2674329Sktlim@umich.edu break; 2684329Sktlim@umich.edu case 0x2: regs = 4; 2694329Sktlim@umich.edu break; 2704329Sktlim@umich.edu default: 2714329Sktlim@umich.edu return new Unknown(machInst); 2722292SN/A } 2732292SN/A break; 2742292SN/A case 2: 2752292SN/A // Regs doesn't behave exactly as it does in the manual 2762292SN/A // because they loop over regs registers twice and we break 2772292SN/A // it down in the macroop. 2782292SN/A switch (type) { 2792292SN/A case 0x8: regs = 2; inc = 1; 2802292SN/A break; 2812292SN/A case 0x9: regs = 2; inc = 2; 2822292SN/A break; 2832292SN/A case 0x3: regs = 4; inc = 2; 2842292SN/A break; 2852292SN/A default: 2869444SAndreas.Sandberg@ARM.com return new Unknown(machInst); 2872307SN/A } 2889444SAndreas.Sandberg@ARM.com break; 2892367SN/A case 3: 2902307SN/A regs = 3; 2912329SN/A switch (type) { 2929444SAndreas.Sandberg@ARM.com case 0x4: inc = 1; 2932307SN/A break; 2942307SN/A case 0x5: inc = 2;; 2952307SN/A break; 2962307SN/A default: 2972307SN/A return new Unknown(machInst); 2982307SN/A } 2999444SAndreas.Sandberg@ARM.com break; 3002307SN/A case 4: 3012307SN/A regs = 4; 3022307SN/A switch (type) { 3032307SN/A case 0: inc = 1; 3042292SN/A break; 3052292SN/A case 1: inc = 2; 3062329SN/A break; 3072329SN/A default: 3082292SN/A return new Unknown(machInst); 3092329SN/A } 3102329SN/A break; 3112292SN/A } 3122292SN/A } 3132292SN/A 3142292SN/A if (load) { 3152292SN/A // Load instructions. 3162329SN/A if (single) { 3172292SN/A return new VldSingle(machInst, singleAll, width, rn, vd, 3182292SN/A regs, inc, size, align, rm, lane); 3199936SFaissal.Sleiman@arm.com } else { 3202292SN/A return new VldMult(machInst, width, rn, vd, 3212292SN/A regs, inc, size, align, rm); 3222292SN/A } 3232292SN/A } else { 3242292SN/A // Store instructions. 3252292SN/A if (single) { 3262329SN/A if (singleAll) { 3272329SN/A return new Unknown(machInst); 3282329SN/A } else { 3292292SN/A return new VstSingle(machInst, false, width, rn, vd, 3302292SN/A regs, inc, size, align, rm, lane); 3312292SN/A } 3322292SN/A } else { 3332292SN/A return new VstMult(machInst, width, rn, vd, 3342329SN/A regs, inc, size, align, rm); 3352292SN/A } 3369936SFaissal.Sleiman@arm.com } 3379936SFaissal.Sleiman@arm.com return new Unknown(machInst); 3382292SN/A } 3392292SN/A ''' 3402292SN/A 3412292SN/A decoder_output += ''' 3422292SN/A static StaticInstPtr 3432292SN/A decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 3442292SN/A { 3452292SN/A const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 3462292SN/A const uint32_t a = bits(machInst, 11, 8); 3472292SN/A const bool b = bits(machInst, 4); 3482292SN/A const uint32_t c = bits(machInst, 21, 20); 3492292SN/A const IntRegIndex vd = 3502292SN/A (IntRegIndex)(2 * (bits(machInst, 15, 12) | 3512292SN/A (bits(machInst, 22) << 4))); 3522292SN/A const IntRegIndex vn = 3532292SN/A (IntRegIndex)(2 * (bits(machInst, 19, 16) | 3542292SN/A (bits(machInst, 7) << 4))); 3552292SN/A const IntRegIndex vm = 3562292SN/A (IntRegIndex)(2 * (bits(machInst, 3, 0) | 3572292SN/A (bits(machInst, 5) << 4))); 3582292SN/A const unsigned size = bits(machInst, 21, 20); 3592292SN/A const bool q = bits(machInst, 6); 3602292SN/A if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1))) 3612329SN/A return new Unknown(machInst); 3622329SN/A switch (a) { 3632292SN/A case 0x0: 3647720Sgblack@eecs.umich.edu if (b) { 3657720Sgblack@eecs.umich.edu if (u) { 3662292SN/A return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 3672292SN/A q, size, machInst, vd, vn, vm); 3682292SN/A } else { 3692292SN/A return decodeNeonSThreeReg<VqaddSD, VqaddSQ>( 3702292SN/A q, size, machInst, vd, vn, vm); 3712292SN/A } 3722292SN/A } else { 3732292SN/A if (size == 3) 3742292SN/A return new Unknown(machInst); 3752292SN/A return decodeNeonUSThreeReg<VhaddD, VhaddQ>( 3762292SN/A q, u, size, machInst, vd, vn, vm); 3772292SN/A } 3782292SN/A case 0x1: 3792292SN/A if (!b) { 3802292SN/A return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>( 3812292SN/A q, u, size, machInst, vd, vn, vm); 3822292SN/A } else { 3832292SN/A if (u) { 3842292SN/A switch (c) { 3852292SN/A case 0: 3862292SN/A if (q) { 3872292SN/A return new VeorQ<uint64_t>(machInst, vd, vn, vm); 3882292SN/A } else { 3892292SN/A return new VeorD<uint64_t>(machInst, vd, vn, vm); 3907720Sgblack@eecs.umich.edu } 3917720Sgblack@eecs.umich.edu case 1: 3922292SN/A if (q) { 3932292SN/A return new VbslQ<uint64_t>(machInst, vd, vn, vm); 3942292SN/A } else { 3952292SN/A return new VbslD<uint64_t>(machInst, vd, vn, vm); 3962292SN/A } 3972292SN/A case 2: 3982292SN/A if (q) { 3992292SN/A return new VbitQ<uint64_t>(machInst, vd, vn, vm); 4002292SN/A } else { 4012292SN/A return new VbitD<uint64_t>(machInst, vd, vn, vm); 4022292SN/A } 4032292SN/A case 3: 4042292SN/A if (q) { 4052292SN/A return new VbifQ<uint64_t>(machInst, vd, vn, vm); 4062292SN/A } else { 4072292SN/A return new VbifD<uint64_t>(machInst, vd, vn, vm); 4082292SN/A } 4092292SN/A } 4102292SN/A } else { 4112292SN/A switch (c) { 4122292SN/A case 0: 4132292SN/A if (q) { 4142292SN/A return new VandQ<uint64_t>(machInst, vd, vn, vm); 4152292SN/A } else { 41610239Sbinhpham@cs.rutgers.edu return new VandD<uint64_t>(machInst, vd, vn, vm); 4172292SN/A } 41810239Sbinhpham@cs.rutgers.edu case 1: 41910239Sbinhpham@cs.rutgers.edu if (q) { 42010239Sbinhpham@cs.rutgers.edu return new VbicQ<uint64_t>(machInst, vd, vn, vm); 42110239Sbinhpham@cs.rutgers.edu } else { 42210239Sbinhpham@cs.rutgers.edu return new VbicD<uint64_t>(machInst, vd, vn, vm); 4232292SN/A } 42410239Sbinhpham@cs.rutgers.edu case 2: 42510239Sbinhpham@cs.rutgers.edu if (vn == vm) { 42610239Sbinhpham@cs.rutgers.edu if (q) { 42710239Sbinhpham@cs.rutgers.edu return new VmovQ<uint64_t>( 42810239Sbinhpham@cs.rutgers.edu machInst, vd, vn, vm); 42910239Sbinhpham@cs.rutgers.edu } else { 43010239Sbinhpham@cs.rutgers.edu return new VmovD<uint64_t>( 43110239Sbinhpham@cs.rutgers.edu machInst, vd, vn, vm); 43210239Sbinhpham@cs.rutgers.edu } 43310239Sbinhpham@cs.rutgers.edu } else { 4342292SN/A if (q) { 4352292SN/A return new VorrQ<uint64_t>( 4368545Ssaidi@eecs.umich.edu machInst, vd, vn, vm); 4378545Ssaidi@eecs.umich.edu } else { 4388545Ssaidi@eecs.umich.edu return new VorrD<uint64_t>( 43911357Sstephan.diestelhorst@arm.com machInst, vd, vn, vm); 44011357Sstephan.diestelhorst@arm.com } 44111357Sstephan.diestelhorst@arm.com } 4428545Ssaidi@eecs.umich.edu case 3: 44310030SAli.Saidi@ARM.com if (q) { 4448545Ssaidi@eecs.umich.edu return new VornQ<uint64_t>( 44511356Skrinat01@arm.com machInst, vd, vn, vm); 44611356Skrinat01@arm.com } else { 44710030SAli.Saidi@ARM.com return new VornD<uint64_t>( 4489383SAli.Saidi@ARM.com machInst, vd, vn, vm); 4499383SAli.Saidi@ARM.com } 4509383SAli.Saidi@ARM.com } 4519383SAli.Saidi@ARM.com } 4529383SAli.Saidi@ARM.com } 4539383SAli.Saidi@ARM.com case 0x2: 4549383SAli.Saidi@ARM.com if (b) { 45510030SAli.Saidi@ARM.com if (u) { 45610030SAli.Saidi@ARM.com return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 45710030SAli.Saidi@ARM.com q, size, machInst, vd, vn, vm); 45810030SAli.Saidi@ARM.com } else { 45911097Songal@cs.wisc.edu return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 46011097Songal@cs.wisc.edu q, size, machInst, vd, vn, vm); 46111097Songal@cs.wisc.edu } 46210030SAli.Saidi@ARM.com } else { 46311097Songal@cs.wisc.edu if (size == 3) 46411097Songal@cs.wisc.edu return new Unknown(machInst); 46511097Songal@cs.wisc.edu return decodeNeonUSThreeReg<VhsubD, VhsubQ>( 46610030SAli.Saidi@ARM.com q, u, size, machInst, vd, vn, vm); 46710030SAli.Saidi@ARM.com } 46810030SAli.Saidi@ARM.com case 0x3: 4698545Ssaidi@eecs.umich.edu if (b) { 4708545Ssaidi@eecs.umich.edu return decodeNeonUSThreeReg<VcgeD, VcgeQ>( 4718545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 47210030SAli.Saidi@ARM.com } else { 4738545Ssaidi@eecs.umich.edu return decodeNeonUSThreeReg<VcgtD, VcgtQ>( 4748545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 47510149Smarco.elver@ed.ac.uk } 47610149Smarco.elver@ed.ac.uk case 0x4: 4778545Ssaidi@eecs.umich.edu if (b) { 4788545Ssaidi@eecs.umich.edu if (u) { 4798545Ssaidi@eecs.umich.edu return decodeNeonUThreeReg<VqshlUD, VqshlUQ>( 48010824SAndreas.Sandberg@ARM.com q, size, machInst, vd, vm, vn); 4818545Ssaidi@eecs.umich.edu } else { 4828545Ssaidi@eecs.umich.edu return decodeNeonSThreeReg<VqshlSD, VqshlSQ>( 4838545Ssaidi@eecs.umich.edu q, size, machInst, vd, vm, vn); 4848545Ssaidi@eecs.umich.edu } 48511097Songal@cs.wisc.edu } else { 48611097Songal@cs.wisc.edu return decodeNeonUSThreeReg<VshlD, VshlQ>( 48711097Songal@cs.wisc.edu q, u, size, machInst, vd, vm, vn); 4888545Ssaidi@eecs.umich.edu } 48911097Songal@cs.wisc.edu case 0x5: 4908545Ssaidi@eecs.umich.edu if (b) { 49111097Songal@cs.wisc.edu if (u) { 49211097Songal@cs.wisc.edu return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>( 49310149Smarco.elver@ed.ac.uk q, size, machInst, vd, vm, vn); 49410149Smarco.elver@ed.ac.uk } else { 49510149Smarco.elver@ed.ac.uk return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>( 49610149Smarco.elver@ed.ac.uk q, size, machInst, vd, vm, vn); 49710149Smarco.elver@ed.ac.uk } 49810149Smarco.elver@ed.ac.uk } else { 49910149Smarco.elver@ed.ac.uk return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 5008545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vm, vn); 50110030SAli.Saidi@ARM.com } 5028545Ssaidi@eecs.umich.edu case 0x6: 5038545Ssaidi@eecs.umich.edu if (b) { 50410474Sandreas.hansson@arm.com return decodeNeonUSThreeReg<VminD, VminQ>( 5058545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 50610030SAli.Saidi@ARM.com } else { 50710030SAli.Saidi@ARM.com return decodeNeonUSThreeReg<VmaxD, VmaxQ>( 50810030SAli.Saidi@ARM.com q, u, size, machInst, vd, vn, vm); 50910030SAli.Saidi@ARM.com } 51010030SAli.Saidi@ARM.com case 0x7: 51110030SAli.Saidi@ARM.com if (b) { 51210030SAli.Saidi@ARM.com return decodeNeonUSThreeReg<VabaD, VabaQ>( 51310030SAli.Saidi@ARM.com q, u, size, machInst, vd, vn, vm); 51410030SAli.Saidi@ARM.com } else { 5158545Ssaidi@eecs.umich.edu if (bits(machInst, 23) == 1) { 5168545Ssaidi@eecs.umich.edu if (q) { 5178545Ssaidi@eecs.umich.edu return new Unknown(machInst); 5189046SAli.Saidi@ARM.com } else { 5198545Ssaidi@eecs.umich.edu return decodeNeonUSThreeUSReg<Vabdl>( 5208545Ssaidi@eecs.umich.edu u, size, machInst, vd, vn, vm); 5218545Ssaidi@eecs.umich.edu } 5228545Ssaidi@eecs.umich.edu } else { 5238545Ssaidi@eecs.umich.edu return decodeNeonUSThreeReg<VabdD, VabdQ>( 5248545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5258545Ssaidi@eecs.umich.edu } 5268545Ssaidi@eecs.umich.edu } 5272292SN/A case 0x8: 5288199SAli.Saidi@ARM.com if (b) { 5298199SAli.Saidi@ARM.com if (u) { 5308199SAli.Saidi@ARM.com return decodeNeonUThreeReg<VceqD, VceqQ>( 5318199SAli.Saidi@ARM.com q, size, machInst, vd, vn, vm); 5328199SAli.Saidi@ARM.com } else { 5338199SAli.Saidi@ARM.com return decodeNeonUThreeReg<VtstD, VtstQ>( 5348199SAli.Saidi@ARM.com q, size, machInst, vd, vn, vm); 5358199SAli.Saidi@ARM.com } 5368199SAli.Saidi@ARM.com } else { 5378199SAli.Saidi@ARM.com if (u) { 5388199SAli.Saidi@ARM.com return decodeNeonUThreeReg<NVsubD, NVsubQ>( 5398199SAli.Saidi@ARM.com q, size, machInst, vd, vn, vm); 54010824SAndreas.Sandberg@ARM.com } else { 5418199SAli.Saidi@ARM.com return decodeNeonUThreeReg<NVaddD, NVaddQ>( 5428199SAli.Saidi@ARM.com q, size, machInst, vd, vn, vm); 5438199SAli.Saidi@ARM.com } 5448199SAli.Saidi@ARM.com } 5458199SAli.Saidi@ARM.com case 0x9: 5468199SAli.Saidi@ARM.com if (b) { 5478199SAli.Saidi@ARM.com if (u) { 5488199SAli.Saidi@ARM.com return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 5498272SAli.Saidi@ARM.com q, size, machInst, vd, vn, vm); 5508545Ssaidi@eecs.umich.edu } else { 5518545Ssaidi@eecs.umich.edu return decodeNeonSThreeReg<NVmulD, NVmulQ>( 5528545Ssaidi@eecs.umich.edu q, size, machInst, vd, vn, vm); 5538545Ssaidi@eecs.umich.edu } 5549046SAli.Saidi@ARM.com } else { 5558545Ssaidi@eecs.umich.edu if (u) { 5568545Ssaidi@eecs.umich.edu return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 5578545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5588592Sgblack@eecs.umich.edu } else { 5598592Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 5608545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5618199SAli.Saidi@ARM.com } 5628545Ssaidi@eecs.umich.edu } 5638199SAli.Saidi@ARM.com case 0xa: 56410474Sandreas.hansson@arm.com if (b) { 56510474Sandreas.hansson@arm.com return decodeNeonUSThreeReg<VpminD, VpminQ>( 56610474Sandreas.hansson@arm.com q, u, size, machInst, vd, vn, vm); 56710474Sandreas.hansson@arm.com } else { 5688545Ssaidi@eecs.umich.edu return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>( 5698545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5708199SAli.Saidi@ARM.com } 5718545Ssaidi@eecs.umich.edu case 0xb: 5728545Ssaidi@eecs.umich.edu if (b) { 5739046SAli.Saidi@ARM.com if (u) { 57410575SMarco.Elver@ARM.com return new Unknown(machInst); 5758545Ssaidi@eecs.umich.edu } else { 5768545Ssaidi@eecs.umich.edu return decodeNeonUThreeReg<NVpaddD, NVpaddQ>( 5778545Ssaidi@eecs.umich.edu q, size, machInst, vd, vn, vm); 5788545Ssaidi@eecs.umich.edu } 5798545Ssaidi@eecs.umich.edu } else { 5808545Ssaidi@eecs.umich.edu if (u) { 5818545Ssaidi@eecs.umich.edu return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>( 5828545Ssaidi@eecs.umich.edu q, size, machInst, vd, vn, vm); 5838545Ssaidi@eecs.umich.edu } else { 5848592Sgblack@eecs.umich.edu return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>( 5858592Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5868592Sgblack@eecs.umich.edu } 5878545Ssaidi@eecs.umich.edu } 5888545Ssaidi@eecs.umich.edu case 0xc: 5898545Ssaidi@eecs.umich.edu return new Unknown(machInst); 5908545Ssaidi@eecs.umich.edu case 0xd: 59110474Sandreas.hansson@arm.com if (b) { 59210474Sandreas.hansson@arm.com if (u) { 59310474Sandreas.hansson@arm.com if (bits(c, 1) == 0) { 59410474Sandreas.hansson@arm.com if (q) { 5958545Ssaidi@eecs.umich.edu return new NVmulQFp<float>(machInst, vd, vn, vm); 5968199SAli.Saidi@ARM.com } else { 5978199SAli.Saidi@ARM.com return new NVmulDFp<float>(machInst, vd, vn, vm); 5988199SAli.Saidi@ARM.com } 5998199SAli.Saidi@ARM.com } else { 6008199SAli.Saidi@ARM.com return new Unknown(machInst); 6018199SAli.Saidi@ARM.com } 6028199SAli.Saidi@ARM.com } else { 6038199SAli.Saidi@ARM.com if (bits(c, 1) == 0) { 6048199SAli.Saidi@ARM.com if (q) { 6058199SAli.Saidi@ARM.com return new NVmlaQFp<float>(machInst, vd, vn, vm); 6068199SAli.Saidi@ARM.com } else { 6078199SAli.Saidi@ARM.com return new NVmlaDFp<float>(machInst, vd, vn, vm); 6082292SN/A } 6092292SN/A } else { 6104032Sktlim@umich.edu if (q) { 6112292SN/A return new NVmlsQFp<float>(machInst, vd, vn, vm); 6122292SN/A } else { 6132292SN/A return new NVmlsDFp<float>(machInst, vd, vn, vm); 6147720Sgblack@eecs.umich.edu } 6157944SGiacomo.Gabrielli@arm.com } 6162292SN/A } 6174032Sktlim@umich.edu } else { 6184032Sktlim@umich.edu if (u) { 6192669Sktlim@umich.edu if (bits(c, 1) == 0) { 6202292SN/A if (q) { 6217944SGiacomo.Gabrielli@arm.com return new VpaddQFp<float>(machInst, vd, vn, vm); 6227944SGiacomo.Gabrielli@arm.com } else { 6237944SGiacomo.Gabrielli@arm.com return new VpaddDFp<float>(machInst, vd, vn, vm); 6247944SGiacomo.Gabrielli@arm.com } 6257597Sminkyu.jeong@arm.com } else { 6267597Sminkyu.jeong@arm.com if (q) { 62710231Ssteve.reinhardt@amd.com return new VabdQFp<float>(machInst, vd, vn, vm); 6282329SN/A } else { 62910824SAndreas.Sandberg@ARM.com return new VabdDFp<float>(machInst, vd, vn, vm); 63010824SAndreas.Sandberg@ARM.com } 63110824SAndreas.Sandberg@ARM.com } 63210231Ssteve.reinhardt@amd.com } else { 6337848SAli.Saidi@ARM.com if (bits(c, 1) == 0) { 6347600Sminkyu.jeong@arm.com if (q) { 6357600Sminkyu.jeong@arm.com return new VaddQFp<float>(machInst, vd, vn, vm); 6367600Sminkyu.jeong@arm.com } else { 63710824SAndreas.Sandberg@ARM.com return new VaddDFp<float>(machInst, vd, vn, vm); 6383731Sktlim@umich.edu } 6392367SN/A } else { 6402367SN/A if (q) { 6412292SN/A return new VsubQFp<float>(machInst, vd, vn, vm); 6422292SN/A } else { 64310333Smitch.hayenga@arm.com return new VsubDFp<float>(machInst, vd, vn, vm); 6449046SAli.Saidi@ARM.com } 6454032Sktlim@umich.edu } 6464032Sktlim@umich.edu } 6474032Sktlim@umich.edu } 6488199SAli.Saidi@ARM.com case 0xe: 6498199SAli.Saidi@ARM.com if (b) { 6502292SN/A if (u) { 6512292SN/A if (bits(c, 1) == 0) { 6522292SN/A if (q) { 6532292SN/A return new VacgeQFp<float>(machInst, vd, vn, vm); 6542292SN/A } else { 6552292SN/A return new VacgeDFp<float>(machInst, vd, vn, vm); 6562292SN/A } 6572292SN/A } else { 6582292SN/A if (q) { 6592292SN/A return new VacgtQFp<float>(machInst, vd, vn, vm); 6602292SN/A } else { 6612292SN/A return new VacgtDFp<float>(machInst, vd, vn, vm); 6622292SN/A } 6632292SN/A } 6642292SN/A } else { 6657720Sgblack@eecs.umich.edu return new Unknown(machInst); 6667720Sgblack@eecs.umich.edu } 6672292SN/A } else { 6684032Sktlim@umich.edu if (u) { 6694032Sktlim@umich.edu if (bits(c, 1) == 0) { 6702292SN/A if (q) { 6712292SN/A return new VcgeQFp<float>(machInst, vd, vn, vm); 6722292SN/A } else { 6732292SN/A return new VcgeDFp<float>(machInst, vd, vn, vm); 6742292SN/A } 6752292SN/A } else { 6767944SGiacomo.Gabrielli@arm.com if (q) { 6777944SGiacomo.Gabrielli@arm.com return new VcgtQFp<float>(machInst, vd, vn, vm); 6787944SGiacomo.Gabrielli@arm.com } else { 6797944SGiacomo.Gabrielli@arm.com return new VcgtDFp<float>(machInst, vd, vn, vm); 68012217Snikos.nikoleris@arm.com } 68112217Snikos.nikoleris@arm.com } 68212217Snikos.nikoleris@arm.com } else { 6837848SAli.Saidi@ARM.com if (bits(c, 1) == 0) { 68412217Snikos.nikoleris@arm.com if (q) { 68512217Snikos.nikoleris@arm.com return new VceqQFp<float>(machInst, vd, vn, vm); 6867848SAli.Saidi@ARM.com } else { 6872329SN/A return new VceqDFp<float>(machInst, vd, vn, vm); 6887782Sminkyu.jeong@arm.com } 6897720Sgblack@eecs.umich.edu } else { 6902292SN/A return new Unknown(machInst); 6912292SN/A } 6922292SN/A } 6932292SN/A } 6942292SN/A case 0xf: 6952292SN/A if (b) { 6962336SN/A if (u) { 6972336SN/A return new Unknown(machInst); 6982336SN/A } else { 6992329SN/A if (bits(c, 1) == 0) { 7002292SN/A if (q) { 7012329SN/A return new VrecpsQFp<float>(machInst, vd, vn, vm); 7022292SN/A } else { 7032292SN/A return new VrecpsDFp<float>(machInst, vd, vn, vm); 7048199SAli.Saidi@ARM.com } 7052292SN/A } else { 7062292SN/A if (q) { 7072292SN/A return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 7082292SN/A } else { 7092292SN/A return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 7102292SN/A } 7112292SN/A } 7122292SN/A } 7132292SN/A } else { 7147720Sgblack@eecs.umich.edu if (u) { 7157720Sgblack@eecs.umich.edu if (bits(c, 1) == 0) { 7162292SN/A if (q) { 7172292SN/A return new VpmaxQFp<float>(machInst, vd, vn, vm); 7182292SN/A } else { 7192292SN/A return new VpmaxDFp<float>(machInst, vd, vn, vm); 7202292SN/A } 7212292SN/A } else { 7222292SN/A if (q) { 7232292SN/A return new VpminQFp<float>(machInst, vd, vn, vm); 7242292SN/A } else { 7252292SN/A return new VpminDFp<float>(machInst, vd, vn, vm); 7262292SN/A } 7272292SN/A } 7282292SN/A } else { 7292292SN/A if (bits(c, 1) == 0) { 7302292SN/A if (q) { 7312292SN/A return new VmaxQFp<float>(machInst, vd, vn, vm); 7322292SN/A } else { 7332292SN/A return new VmaxDFp<float>(machInst, vd, vn, vm); 7342292SN/A } 7352292SN/A } else { 7362292SN/A if (q) { 7372292SN/A return new VminQFp<float>(machInst, vd, vn, vm); 7382292SN/A } else { 7392292SN/A return new VminDFp<float>(machInst, vd, vn, vm); 7402292SN/A } 7412292SN/A } 7422292SN/A } 7432292SN/A } 7442292SN/A } 7452329SN/A return new Unknown(machInst); 7462329SN/A } 7472292SN/A 7482292SN/A static StaticInstPtr 7492292SN/A decodeNeonOneRegModImm(ExtMachInst machInst) 7502292SN/A { 7512292SN/A const IntRegIndex vd = 7527720Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 7537720Sgblack@eecs.umich.edu (bits(machInst, 22) << 4))); 7542292SN/A const bool q = bits(machInst, 6); 7552292SN/A const bool op = bits(machInst, 5); 7562292SN/A const uint8_t cmode = bits(machInst, 11, 8); 7572292SN/A const uint8_t imm = ((THUMB ? bits(machInst, 28) : 7582292SN/A bits(machInst, 24)) << 7) | 7592292SN/A (bits(machInst, 18, 16) << 4) | 7602292SN/A (bits(machInst, 3, 0) << 0); 7612292SN/A const uint64_t bigImm = simd_modified_imm(op, cmode, imm); 7622292SN/A if (op) { 7632292SN/A if (bits(cmode, 3) == 0) { 7642292SN/A if (bits(cmode, 0) == 0) { 7652292SN/A if (q) 7662292SN/A return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 7676974Stjones1@inf.ed.ac.uk else 7686974Stjones1@inf.ed.ac.uk return new NVmvniD<uint64_t>(machInst, vd, bigImm); 7696974Stjones1@inf.ed.ac.uk } else { 7706974Stjones1@inf.ed.ac.uk if (q) 7716974Stjones1@inf.ed.ac.uk return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 7726974Stjones1@inf.ed.ac.uk else 7736974Stjones1@inf.ed.ac.uk return new NVbiciD<uint64_t>(machInst, vd, bigImm); 7746974Stjones1@inf.ed.ac.uk } 7756974Stjones1@inf.ed.ac.uk } else { 7766974Stjones1@inf.ed.ac.uk if (bits(cmode, 2) == 1) { 7776974Stjones1@inf.ed.ac.uk switch (bits(cmode, 1, 0)) { 7786974Stjones1@inf.ed.ac.uk case 0: 7796974Stjones1@inf.ed.ac.uk case 1: 7806974Stjones1@inf.ed.ac.uk if (q) 7816974Stjones1@inf.ed.ac.uk return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 7826974Stjones1@inf.ed.ac.uk else 7832292SN/A return new NVmvniD<uint64_t>(machInst, vd, bigImm); 7842292SN/A case 2: 7856974Stjones1@inf.ed.ac.uk if (q) 7866974Stjones1@inf.ed.ac.uk return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 7876974Stjones1@inf.ed.ac.uk else 7886974Stjones1@inf.ed.ac.uk return new NVmoviD<uint64_t>(machInst, vd, bigImm); 7896974Stjones1@inf.ed.ac.uk case 3: 7906974Stjones1@inf.ed.ac.uk if (q) 7912292SN/A return new Unknown(machInst); 7922292SN/A else 7932292SN/A return new Unknown(machInst); 7942292SN/A } 7958727Snilay@cs.wisc.edu } else { 79611780Sarthur.perais@inria.fr if (bits(cmode, 0) == 0) { 7972292SN/A if (q) 79810333Smitch.hayenga@arm.com return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 7992678Sktlim@umich.edu else 8002678Sktlim@umich.edu return new NVmvniD<uint64_t>(machInst, vd, bigImm); 8012678Sktlim@umich.edu } else { 8022678Sktlim@umich.edu if (q) 8032678Sktlim@umich.edu return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 8042329SN/A else 8052329SN/A return new NVbiciD<uint64_t>(machInst, vd, bigImm); 8062292SN/A } 8072292SN/A } 8082292SN/A } 8092292SN/A } else { 8102292SN/A if (bits(cmode, 3) == 0) { 8112292SN/A if (bits(cmode, 0) == 0) { 8122292SN/A if (q) 8132678Sktlim@umich.edu return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 81411780Sarthur.perais@inria.fr else 8152292SN/A return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8162292SN/A } else { 8172292SN/A if (q) 8182292SN/A return new NVorriQ<uint64_t>(machInst, vd, bigImm); 8192292SN/A else 8202292SN/A return new NVorriD<uint64_t>(machInst, vd, bigImm); 8212292SN/A } 8222292SN/A } else { 8232292SN/A if (bits(cmode, 2) == 1) { 8242292SN/A if (q) 8256974Stjones1@inf.ed.ac.uk return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8266974Stjones1@inf.ed.ac.uk else 8276974Stjones1@inf.ed.ac.uk return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8286974Stjones1@inf.ed.ac.uk } else { 8296974Stjones1@inf.ed.ac.uk if (bits(cmode, 0) == 0) { 8302669Sktlim@umich.edu if (q) 8312669Sktlim@umich.edu return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 83212749Sgiacomo.travaglini@arm.com else 83312749Sgiacomo.travaglini@arm.com return new NVmoviD<uint64_t>(machInst, vd, bigImm); 83412749Sgiacomo.travaglini@arm.com } else { 8358481Sgblack@eecs.umich.edu if (q) 8362292SN/A return new NVorriQ<uint64_t>(machInst, vd, bigImm); 8372292SN/A else 8382669Sktlim@umich.edu return new NVorriD<uint64_t>(machInst, vd, bigImm); 83910031SAli.Saidi@ARM.com } 8403772Sgblack@eecs.umich.edu } 84110031SAli.Saidi@ARM.com } 84210031SAli.Saidi@ARM.com } 84310031SAli.Saidi@ARM.com return new Unknown(machInst); 84410031SAli.Saidi@ARM.com } 8452669Sktlim@umich.edu 8466974Stjones1@inf.ed.ac.uk static StaticInstPtr 8476974Stjones1@inf.ed.ac.uk decodeNeonTwoRegAndShift(ExtMachInst machInst) 8482292SN/A { 8492678Sktlim@umich.edu const uint32_t a = bits(machInst, 11, 8); 8502678Sktlim@umich.edu const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 8512678Sktlim@umich.edu const bool b = bits(machInst, 6); 8522678Sktlim@umich.edu const bool l = bits(machInst, 7); 8536974Stjones1@inf.ed.ac.uk const IntRegIndex vd = 8546974Stjones1@inf.ed.ac.uk (IntRegIndex)(2 * (bits(machInst, 15, 12) | 8556974Stjones1@inf.ed.ac.uk (bits(machInst, 22) << 4))); 8566974Stjones1@inf.ed.ac.uk const IntRegIndex vm = 85710342SCurtis.Dunham@arm.com (IntRegIndex)(2 * (bits(machInst, 3, 0) | 8586974Stjones1@inf.ed.ac.uk (bits(machInst, 5) << 4))); 8596974Stjones1@inf.ed.ac.uk unsigned imm6 = bits(machInst, 21, 16); 8606974Stjones1@inf.ed.ac.uk unsigned imm = ((l ? 1 : 0) << 6) | imm6; 8616974Stjones1@inf.ed.ac.uk unsigned size = 3; 86210342SCurtis.Dunham@arm.com unsigned lShiftAmt = 0; 86310342SCurtis.Dunham@arm.com unsigned bitSel; 8646974Stjones1@inf.ed.ac.uk for (bitSel = 1 << 6; true; bitSel >>= 1) { 8656974Stjones1@inf.ed.ac.uk if (bitSel & imm) 8666974Stjones1@inf.ed.ac.uk break; 8676974Stjones1@inf.ed.ac.uk else if (!size) 8686974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 8696974Stjones1@inf.ed.ac.uk size--; 8706974Stjones1@inf.ed.ac.uk } 8716974Stjones1@inf.ed.ac.uk lShiftAmt = imm6 & ~bitSel; 8726974Stjones1@inf.ed.ac.uk unsigned rShiftAmt = 0; 8736974Stjones1@inf.ed.ac.uk if (a != 0xe && a != 0xf) { 8746974Stjones1@inf.ed.ac.uk if (size > 2) 8756974Stjones1@inf.ed.ac.uk rShiftAmt = 64 - imm6; 8766974Stjones1@inf.ed.ac.uk else 8772678Sktlim@umich.edu rShiftAmt = 2 * (8 << size) - imm6; 8787720Sgblack@eecs.umich.edu } 8792292SN/A 8807720Sgblack@eecs.umich.edu switch (a) { 8813797Sgblack@eecs.umich.edu case 0x0: 8823221Sktlim@umich.edu return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 8832292SN/A b, u, size, machInst, vd, vm, rShiftAmt); 8842693Sktlim@umich.edu case 0x1: 8854350Sgblack@eecs.umich.edu return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 8866974Stjones1@inf.ed.ac.uk b, u, size, machInst, vd, vm, rShiftAmt); 8873326Sktlim@umich.edu case 0x2: 8883326Sktlim@umich.edu return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 8893326Sktlim@umich.edu b, u, size, machInst, vd, vm, rShiftAmt); 8909046SAli.Saidi@ARM.com case 0x3: 89110030SAli.Saidi@ARM.com return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 8929046SAli.Saidi@ARM.com b, u, size, machInst, vd, vm, rShiftAmt); 8933326Sktlim@umich.edu case 0x4: 8943326Sktlim@umich.edu if (u) { 8953326Sktlim@umich.edu return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 8963326Sktlim@umich.edu b, size, machInst, vd, vm, rShiftAmt); 8973326Sktlim@umich.edu } else { 8983326Sktlim@umich.edu return new Unknown(machInst); 8993326Sktlim@umich.edu } 9007823Ssteve.reinhardt@amd.com case 0x5: 9013326Sktlim@umich.edu if (u) { 9023326Sktlim@umich.edu return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 9033326Sktlim@umich.edu b, size, machInst, vd, vm, lShiftAmt); 9042693Sktlim@umich.edu } else { 9052693Sktlim@umich.edu return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 9062693Sktlim@umich.edu b, size, machInst, vd, vm, lShiftAmt); 9072693Sktlim@umich.edu } 9082693Sktlim@umich.edu case 0x6: 9092693Sktlim@umich.edu case 0x7: 9108481Sgblack@eecs.umich.edu if (u) { 9118481Sgblack@eecs.umich.edu if (a == 0x6) { 9128481Sgblack@eecs.umich.edu return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 9138481Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9148481Sgblack@eecs.umich.edu } else { 9158481Sgblack@eecs.umich.edu return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 9168481Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9178481Sgblack@eecs.umich.edu } 9188481Sgblack@eecs.umich.edu } else { 9198481Sgblack@eecs.umich.edu return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 9208481Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9218481Sgblack@eecs.umich.edu } 9228481Sgblack@eecs.umich.edu case 0x8: 9238481Sgblack@eecs.umich.edu if (l) { 9248481Sgblack@eecs.umich.edu return new Unknown(machInst); 9258481Sgblack@eecs.umich.edu } else if (u) { 9268481Sgblack@eecs.umich.edu return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 9278481Sgblack@eecs.umich.edu b, size, machInst, vd, vm, rShiftAmt); 9284032Sktlim@umich.edu } else { 9293221Sktlim@umich.edu return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 9303221Sktlim@umich.edu b, size, machInst, vd, vm, rShiftAmt); 9316974Stjones1@inf.ed.ac.uk } 9326974Stjones1@inf.ed.ac.uk case 0x9: 9338481Sgblack@eecs.umich.edu if (l) { 9346974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 9356974Stjones1@inf.ed.ac.uk } else if (u) { 9366974Stjones1@inf.ed.ac.uk return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 9372669Sktlim@umich.edu b, size, machInst, vd, vm, rShiftAmt); 9386974Stjones1@inf.ed.ac.uk } else { 9396974Stjones1@inf.ed.ac.uk return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 9408481Sgblack@eecs.umich.edu b, size, machInst, vd, vm, rShiftAmt); 9416974Stjones1@inf.ed.ac.uk } 9426974Stjones1@inf.ed.ac.uk case 0xa: 9436974Stjones1@inf.ed.ac.uk if (l || b) { 94411780Sarthur.perais@inria.fr return new Unknown(machInst); 94511780Sarthur.perais@inria.fr } else { 9466974Stjones1@inf.ed.ac.uk return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 9476974Stjones1@inf.ed.ac.uk lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); 9486974Stjones1@inf.ed.ac.uk } 9496974Stjones1@inf.ed.ac.uk case 0xe: 9506974Stjones1@inf.ed.ac.uk if (l) { 9516974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 9526974Stjones1@inf.ed.ac.uk } else { 9536974Stjones1@inf.ed.ac.uk if (bits(imm6, 5) == 0) 9546974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 9556974Stjones1@inf.ed.ac.uk if (u) { 9566974Stjones1@inf.ed.ac.uk if (b) { 9576974Stjones1@inf.ed.ac.uk return new NVcvtu2fpQ<float>( 9586974Stjones1@inf.ed.ac.uk machInst, vd, vm, 64 - imm6); 9596974Stjones1@inf.ed.ac.uk } else { 9606974Stjones1@inf.ed.ac.uk return new NVcvtu2fpD<float>( 9616974Stjones1@inf.ed.ac.uk machInst, vd, vm, 64 - imm6); 9626974Stjones1@inf.ed.ac.uk } 9636974Stjones1@inf.ed.ac.uk } else { 9646974Stjones1@inf.ed.ac.uk if (b) { 9652292SN/A return new NVcvts2fpQ<float>( 9662292SN/A machInst, vd, vm, 64 - imm6); 9672292SN/A } else { 9682292SN/A return new NVcvts2fpD<float>( 96911780Sarthur.perais@inria.fr machInst, vd, vm, 64 - imm6); 9702292SN/A } 9712292SN/A } 9722292SN/A } 9732292SN/A case 0xf: 9742292SN/A if (l) { 9752292SN/A return new Unknown(machInst); 9762292SN/A } else { 9772292SN/A if (bits(imm6, 5) == 0) 9782292SN/A return new Unknown(machInst); 9792292SN/A if (u) { 9802292SN/A if (b) { 9812292SN/A return new NVcvt2ufxQ<float>( 9822292SN/A machInst, vd, vm, 64 - imm6); 9832292SN/A } else { 9842292SN/A return new NVcvt2ufxD<float>( 9852292SN/A machInst, vd, vm, 64 - imm6); 9862292SN/A } 9872292SN/A } else { 9882292SN/A if (b) { 9892292SN/A return new NVcvt2sfxQ<float>( 9902292SN/A machInst, vd, vm, 64 - imm6); 9912292SN/A } else { 9922292SN/A return new NVcvt2sfxD<float>( 9932329SN/A machInst, vd, vm, 64 - imm6); 9942292SN/A } 9952292SN/A } 9962292SN/A } 9972292SN/A } 9982292SN/A return new Unknown(machInst); 9997720Sgblack@eecs.umich.edu } 10002292SN/A 10017720Sgblack@eecs.umich.edu static StaticInstPtr 10022292SN/A decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 10032292SN/A { 10042292SN/A const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 10052292SN/A const uint32_t a = bits(machInst, 11, 8); 10062292SN/A const IntRegIndex vd = 10072292SN/A (IntRegIndex)(2 * (bits(machInst, 15, 12) | 10082292SN/A (bits(machInst, 22) << 4))); 10092292SN/A const IntRegIndex vn = 10102329SN/A (IntRegIndex)(2 * (bits(machInst, 19, 16) | 10112731Sktlim@umich.edu (bits(machInst, 7) << 4))); 10122292SN/A const IntRegIndex vm = 10132292SN/A (IntRegIndex)(2 * (bits(machInst, 3, 0) | 10142292SN/A (bits(machInst, 5) << 4))); 10152292SN/A const unsigned size = bits(machInst, 21, 20); 10162292SN/A switch (a) { 10172292SN/A case 0x0: 10182292SN/A return decodeNeonUSThreeUSReg<Vaddl>( 10192727Sktlim@umich.edu u, size, machInst, vd, vn, vm); 10202292SN/A case 0x1: 10212292SN/A return decodeNeonUSThreeUSReg<Vaddw>( 10224032Sktlim@umich.edu u, size, machInst, vd, vn, vm); 10234032Sktlim@umich.edu case 0x2: 10244032Sktlim@umich.edu return decodeNeonUSThreeUSReg<Vsubl>( 10254032Sktlim@umich.edu u, size, machInst, vd, vn, vm); 10262292SN/A case 0x3: 10272292SN/A return decodeNeonUSThreeUSReg<Vsubw>( 10282292SN/A u, size, machInst, vd, vn, vm); 10292292SN/A case 0x4: 10302292SN/A if (u) { 10312329SN/A return decodeNeonUThreeUSReg<Vraddhn>( 10322292SN/A size, machInst, vd, vn, vm); 10332292SN/A } else { 10342292SN/A return decodeNeonUThreeUSReg<Vaddhn>( 10352292SN/A size, machInst, vd, vn, vm); 10367720Sgblack@eecs.umich.edu } 10372292SN/A case 0x5: 10387720Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vabal>( 10392292SN/A u, size, machInst, vd, vn, vm); 10402292SN/A case 0x6: 10412329SN/A if (u) { 10422329SN/A return decodeNeonUThreeUSReg<Vrsubhn>( 10432292SN/A size, machInst, vd, vn, vm); 10442292SN/A } else { 10452292SN/A return decodeNeonUThreeUSReg<Vsubhn>( 10462292SN/A size, machInst, vd, vn, vm); 10472292SN/A } 10482292SN/A case 0x7: 10492292SN/A if (bits(machInst, 23)) { 10502329SN/A return decodeNeonUSThreeUSReg<Vabdl>( 10512731Sktlim@umich.edu u, size, machInst, vd, vn, vm); 10522292SN/A } else { 10532292SN/A return decodeNeonUSThreeReg<VabdD, VabdQ>( 10542292SN/A bits(machInst, 6), u, size, machInst, vd, vn, vm); 10554032Sktlim@umich.edu } 10564032Sktlim@umich.edu case 0x8: 10574032Sktlim@umich.edu return decodeNeonUSThreeUSReg<Vmlal>( 105812749Sgiacomo.travaglini@arm.com u, size, machInst, vd, vn, vm); 10596974Stjones1@inf.ed.ac.uk case 0xa: 106012749Sgiacomo.travaglini@arm.com return decodeNeonUSThreeUSReg<Vmlsl>( 106112749Sgiacomo.travaglini@arm.com u, size, machInst, vd, vn, vm); 10626974Stjones1@inf.ed.ac.uk case 0x9: 10634032Sktlim@umich.edu if (u) { 10642292SN/A return new Unknown(machInst); 10652292SN/A } else { 10662292SN/A return decodeNeonSThreeUSReg<Vqdmlal>( 10672292SN/A size, machInst, vd, vn, vm); 10682292SN/A } 10692292SN/A case 0xb: 10702727Sktlim@umich.edu if (u) { 10712292SN/A return new Unknown(machInst); 10722292SN/A } else { 10732292SN/A return decodeNeonSThreeUSReg<Vqdmlsl>( 10742292SN/A size, machInst, vd, vn, vm); 10752292SN/A } 10763349Sbinkertn@umich.edu case 0xc: 10772693Sktlim@umich.edu return decodeNeonUSThreeUSReg<Vmull>( 10782693Sktlim@umich.edu u, size, machInst, vd, vn, vm); 10792693Sktlim@umich.edu case 0xd: 10802693Sktlim@umich.edu if (u) { 10812693Sktlim@umich.edu return new Unknown(machInst); 10822693Sktlim@umich.edu } else { 10832693Sktlim@umich.edu return decodeNeonSThreeUSReg<Vqdmull>( 10842693Sktlim@umich.edu size, machInst, vd, vn, vm); 10852693Sktlim@umich.edu } 10862693Sktlim@umich.edu case 0xe: 10872693Sktlim@umich.edu return decodeNeonUThreeUSReg<Vmullp>( 10882693Sktlim@umich.edu size, machInst, vd, vn, vm); 10892693Sktlim@umich.edu } 10902693Sktlim@umich.edu return new Unknown(machInst); 10912693Sktlim@umich.edu } 10922693Sktlim@umich.edu 10938887Sgeoffrey.blake@arm.com static StaticInstPtr 10942693Sktlim@umich.edu decodeNeonTwoRegScalar(ExtMachInst machInst) 10952732Sktlim@umich.edu { 10962693Sktlim@umich.edu const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 10972693Sktlim@umich.edu const uint32_t a = bits(machInst, 11, 8); 10982693Sktlim@umich.edu const unsigned size = bits(machInst, 21, 20); 10998727Snilay@cs.wisc.edu const IntRegIndex vd = 11008727Snilay@cs.wisc.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 11018727Snilay@cs.wisc.edu (bits(machInst, 22) << 4))); 11028727Snilay@cs.wisc.edu const IntRegIndex vn = 11032693Sktlim@umich.edu (IntRegIndex)(2 * (bits(machInst, 19, 16) | 11042693Sktlim@umich.edu (bits(machInst, 7) << 4))); 11052693Sktlim@umich.edu const IntRegIndex vm = (size == 2) ? 11062693Sktlim@umich.edu (IntRegIndex)(2 * bits(machInst, 3, 0)) : 11072693Sktlim@umich.edu (IntRegIndex)(2 * bits(machInst, 2, 0)); 11082678Sktlim@umich.edu const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 11092678Sktlim@umich.edu (bits(machInst, 3) | (bits(machInst, 5) << 1)); 11102678Sktlim@umich.edu switch (a) { 11112678Sktlim@umich.edu case 0x0: 11122678Sktlim@umich.edu if (u) { 11132678Sktlim@umich.edu switch (size) { 11142678Sktlim@umich.edu case 1: 11152727Sktlim@umich.edu return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 11162678Sktlim@umich.edu case 2: 11172678Sktlim@umich.edu return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index); 11182678Sktlim@umich.edu default: 11192678Sktlim@umich.edu return new Unknown(machInst); 11202678Sktlim@umich.edu } 11212678Sktlim@umich.edu } else { 112210575SMarco.Elver@ARM.com switch (size) { 112310575SMarco.Elver@ARM.com case 1: 112410575SMarco.Elver@ARM.com return new VmlasD<uint16_t>(machInst, vd, vn, vm, index); 112510575SMarco.Elver@ARM.com case 2: 112610575SMarco.Elver@ARM.com return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 112710575SMarco.Elver@ARM.com default: 112810575SMarco.Elver@ARM.com return new Unknown(machInst); 112910575SMarco.Elver@ARM.com } 113010575SMarco.Elver@ARM.com } 113110575SMarco.Elver@ARM.com case 0x1: 113210575SMarco.Elver@ARM.com if (u) 113310575SMarco.Elver@ARM.com return new VmlasQFp<float>(machInst, vd, vn, vm, index); 113410575SMarco.Elver@ARM.com else 113510575SMarco.Elver@ARM.com return new VmlasDFp<float>(machInst, vd, vn, vm, index); 11362678Sktlim@umich.edu case 0x4: 11372678Sktlim@umich.edu if (u) { 11382678Sktlim@umich.edu switch (size) { 11392678Sktlim@umich.edu case 1: 11402678Sktlim@umich.edu return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 11412678Sktlim@umich.edu case 2: 11427598Sminkyu.jeong@arm.com return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index); 11437598Sminkyu.jeong@arm.com default: 11447598Sminkyu.jeong@arm.com return new Unknown(machInst); 11452678Sktlim@umich.edu } 11462678Sktlim@umich.edu } else { 11472678Sktlim@umich.edu switch (size) { 11482678Sktlim@umich.edu case 1: 11492292SN/A return new VmlssD<uint16_t>(machInst, vd, vn, vm, index); 11502292SN/A case 2: 11512292SN/A return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 11522292SN/A default: 11532292SN/A return new Unknown(machInst); 11542292SN/A } 11552292SN/A } 11562292SN/A case 0x5: 11573126Sktlim@umich.edu if (u) 11582292SN/A return new VmlssQFp<float>(machInst, vd, vn, vm, index); 11592292SN/A else 11602292SN/A return new VmlssDFp<float>(machInst, vd, vn, vm, index); 11612292SN/A case 0x2: 11622292SN/A if (u) { 11632292SN/A switch (size) { 11642292SN/A case 1: 11652292SN/A return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 11662292SN/A case 2: 11672292SN/A return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 11682292SN/A default: 11692292SN/A return new Unknown(machInst); 11702292SN/A } 11712329SN/A } else { 11722329SN/A switch (size) { 11732329SN/A case 1: 11742292SN/A return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 11759527SMatt.Horsnell@arm.com case 2: 11769527SMatt.Horsnell@arm.com return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 11779527SMatt.Horsnell@arm.com default: 11789527SMatt.Horsnell@arm.com return new Unknown(machInst); 11799527SMatt.Horsnell@arm.com } 11809527SMatt.Horsnell@arm.com } 11819527SMatt.Horsnell@arm.com case 0x6: 11822292SN/A if (u) { 11832292SN/A switch (size) { 11842292SN/A case 1: 11852292SN/A return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 11862292SN/A case 2: 11872292SN/A return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 11882292SN/A default: 11892292SN/A return new Unknown(machInst); 11902292SN/A } 11912316SN/A } else { 11922316SN/A switch (size) { 11932329SN/A case 1: 11948727Snilay@cs.wisc.edu return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 11958727Snilay@cs.wisc.edu case 2: 11968727Snilay@cs.wisc.edu return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 11978727Snilay@cs.wisc.edu default: 11982329SN/A return new Unknown(machInst); 11992329SN/A } 12002329SN/A } 120112216Snikos.nikoleris@arm.com case 0x3: 120212216Snikos.nikoleris@arm.com if (u) { 120312216Snikos.nikoleris@arm.com return new Unknown(machInst); 120412216Snikos.nikoleris@arm.com } else { 120512216Snikos.nikoleris@arm.com switch (size) { 12062732Sktlim@umich.edu case 1: 12072316SN/A return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 12082292SN/A case 2: 12092292SN/A return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 12102292SN/A default: 12116974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 12126974Stjones1@inf.ed.ac.uk } 12136974Stjones1@inf.ed.ac.uk } 12148975Sandreas.hansson@arm.com case 0x7: 12156974Stjones1@inf.ed.ac.uk if (u) { 12166974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 12176974Stjones1@inf.ed.ac.uk } else { 12186974Stjones1@inf.ed.ac.uk switch (size) { 12196974Stjones1@inf.ed.ac.uk case 1: 12206974Stjones1@inf.ed.ac.uk return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 12216974Stjones1@inf.ed.ac.uk case 2: 12226974Stjones1@inf.ed.ac.uk return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 12236974Stjones1@inf.ed.ac.uk default: 12246974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 12256974Stjones1@inf.ed.ac.uk } 12262693Sktlim@umich.edu } 12272693Sktlim@umich.edu case 0x8: 12282693Sktlim@umich.edu if (u) { 12292698Sktlim@umich.edu switch (size) { 12304985Sktlim@umich.edu case 1: 12312698Sktlim@umich.edu return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 12322693Sktlim@umich.edu case 2: 12338587Snilay@cs.wisc.edu return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index); 12348587Snilay@cs.wisc.edu default: 12358587Snilay@cs.wisc.edu return new Unknown(machInst); 12368975Sandreas.hansson@arm.com } 12376974Stjones1@inf.ed.ac.uk } else { 12388133SAli.Saidi@ARM.com switch (size) { 12398133SAli.Saidi@ARM.com case 1: 12408133SAli.Saidi@ARM.com return new VmulsD<uint16_t>(machInst, vd, vn, vm, index); 12416974Stjones1@inf.ed.ac.uk case 2: 12426974Stjones1@inf.ed.ac.uk return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 12432699Sktlim@umich.edu default: 12442693Sktlim@umich.edu return new Unknown(machInst); 12456974Stjones1@inf.ed.ac.uk } 12466974Stjones1@inf.ed.ac.uk } 12476974Stjones1@inf.ed.ac.uk case 0x9: 12486974Stjones1@inf.ed.ac.uk if (u) 12496974Stjones1@inf.ed.ac.uk return new VmulsQFp<float>(machInst, vd, vn, vm, index); 12506974Stjones1@inf.ed.ac.uk else 12516974Stjones1@inf.ed.ac.uk return new VmulsDFp<float>(machInst, vd, vn, vm, index); 12526974Stjones1@inf.ed.ac.uk case 0xa: 12532693Sktlim@umich.edu if (u) { 12542693Sktlim@umich.edu switch (size) { 12552727Sktlim@umich.edu case 1: 12562693Sktlim@umich.edu return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 12572693Sktlim@umich.edu case 2: 12582693Sktlim@umich.edu return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 12592693Sktlim@umich.edu default: 12602693Sktlim@umich.edu return new Unknown(machInst); 12612292SN/A } 12629440SAndreas.Sandberg@ARM.com } else { 12632292SN/A switch (size) { 12642292SN/A case 1: 12652292SN/A return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 12662292SN/A case 2: 12672292SN/A return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 12682292SN/A default: 12692292SN/A return new Unknown(machInst); 12709440SAndreas.Sandberg@ARM.com } 12712292SN/A } 12722292SN/A case 0xb: 12732292SN/A if (u) { 12742292SN/A return new Unknown(machInst); 12752292SN/A } else { 12762292SN/A if (u) { 12772292SN/A switch (size) { 12789440SAndreas.Sandberg@ARM.com case 1: 12792292SN/A return new Vqdmulls<uint16_t>( 12802292SN/A machInst, vd, vn, vm, index); 12812292SN/A case 2: 12822292SN/A return new Vqdmulls<uint32_t>( 12832292SN/A machInst, vd, vn, vm, index); 12842292SN/A default: 12852292SN/A return new Unknown(machInst); 12869440SAndreas.Sandberg@ARM.com } 12872292SN/A } else { 12882292SN/A switch (size) { 12892292SN/A case 1: 12902292SN/A return new Vqdmulls<int16_t>( 12912329SN/A machInst, vd, vn, vm, index); 12922329SN/A case 2: 12932329SN/A return new Vqdmulls<int32_t>( 12949440SAndreas.Sandberg@ARM.com machInst, vd, vn, vm, index); 12952329SN/A default: 12962329SN/A return new Unknown(machInst); 12972329SN/A } 12982329SN/A } 12992329SN/A } 13002329SN/A case 0xc: 13012329SN/A if (u) { 13022329SN/A switch (size) { 13039440SAndreas.Sandberg@ARM.com case 1: 13049440SAndreas.Sandberg@ARM.com return new VqdmulhsQ<int16_t>( 13052329SN/A machInst, vd, vn, vm, index); 13062329SN/A case 2: 13072329SN/A return new VqdmulhsQ<int32_t>( 13089440SAndreas.Sandberg@ARM.com machInst, vd, vn, vm, index); 13092329SN/A default: 13102329SN/A return new Unknown(machInst); 13112329SN/A } 13122329SN/A } else { 13132329SN/A switch (size) { 13142329SN/A case 1: 13152329SN/A return new VqdmulhsD<int16_t>( 13169440SAndreas.Sandberg@ARM.com machInst, vd, vn, vm, index); 13179440SAndreas.Sandberg@ARM.com case 2: 13182329SN/A return new VqdmulhsD<int32_t>( 13192329SN/A machInst, vd, vn, vm, index); 13202329SN/A default: 13212329SN/A return new Unknown(machInst); 13222329SN/A } 13232329SN/A } 13249944Smatt.horsnell@ARM.com case 0xd: 13259944Smatt.horsnell@ARM.com if (u) { 1326 switch (size) { 1327 case 1: 1328 return new VqrdmulhsQ<int16_t>( 1329 machInst, vd, vn, vm, index); 1330 case 2: 1331 return new VqrdmulhsQ<int32_t>( 1332 machInst, vd, vn, vm, index); 1333 default: 1334 return new Unknown(machInst); 1335 } 1336 } else { 1337 switch (size) { 1338 case 1: 1339 return new VqrdmulhsD<int16_t>( 1340 machInst, vd, vn, vm, index); 1341 case 2: 1342 return new VqrdmulhsD<int32_t>( 1343 machInst, vd, vn, vm, index); 1344 default: 1345 return new Unknown(machInst); 1346 } 1347 } 1348 } 1349 return new Unknown(machInst); 1350 } 1351 1352 static StaticInstPtr 1353 decodeNeonTwoRegMisc(ExtMachInst machInst) 1354 { 1355 const uint32_t a = bits(machInst, 17, 16); 1356 const uint32_t b = bits(machInst, 10, 6); 1357 const bool q = bits(machInst, 6); 1358 const IntRegIndex vd = 1359 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1360 (bits(machInst, 22) << 4))); 1361 const IntRegIndex vm = 1362 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1363 (bits(machInst, 5) << 4))); 1364 const unsigned size = bits(machInst, 19, 18); 1365 switch (a) { 1366 case 0x0: 1367 switch (bits(b, 4, 1)) { 1368 case 0x0: 1369 switch (size) { 1370 case 0: 1371 if (q) { 1372 return new NVrev64Q<uint8_t>(machInst, vd, vm); 1373 } else { 1374 return new NVrev64D<uint8_t>(machInst, vd, vm); 1375 } 1376 case 1: 1377 if (q) { 1378 return new NVrev64Q<uint16_t>(machInst, vd, vm); 1379 } else { 1380 return new NVrev64D<uint16_t>(machInst, vd, vm); 1381 } 1382 case 2: 1383 if (q) { 1384 return new NVrev64Q<uint32_t>(machInst, vd, vm); 1385 } else { 1386 return new NVrev64D<uint32_t>(machInst, vd, vm); 1387 } 1388 default: 1389 return new Unknown(machInst); 1390 } 1391 case 0x1: 1392 switch (size) { 1393 case 0: 1394 if (q) { 1395 return new NVrev32Q<uint8_t>(machInst, vd, vm); 1396 } else { 1397 return new NVrev32D<uint8_t>(machInst, vd, vm); 1398 } 1399 case 1: 1400 if (q) { 1401 return new NVrev32Q<uint16_t>(machInst, vd, vm); 1402 } else { 1403 return new NVrev32D<uint16_t>(machInst, vd, vm); 1404 } 1405 default: 1406 return new Unknown(machInst); 1407 } 1408 case 0x2: 1409 if (size != 0) { 1410 return new Unknown(machInst); 1411 } else if (q) { 1412 return new NVrev16Q<uint8_t>(machInst, vd, vm); 1413 } else { 1414 return new NVrev16D<uint8_t>(machInst, vd, vm); 1415 } 1416 case 0x4: 1417 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1418 q, size, machInst, vd, vm); 1419 case 0x5: 1420 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1421 q, size, machInst, vd, vm); 1422 case 0x8: 1423 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 1424 q, size, machInst, vd, vm); 1425 case 0x9: 1426 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 1427 q, size, machInst, vd, vm); 1428 case 0xa: 1429 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 1430 q, size, machInst, vd, vm); 1431 case 0xb: 1432 if (q) 1433 return new NVmvnQ<uint64_t>(machInst, vd, vm); 1434 else 1435 return new NVmvnD<uint64_t>(machInst, vd, vm); 1436 case 0xc: 1437 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 1438 q, size, machInst, vd, vm); 1439 case 0xd: 1440 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 1441 q, size, machInst, vd, vm); 1442 case 0xe: 1443 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 1444 q, size, machInst, vd, vm); 1445 case 0xf: 1446 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 1447 q, size, machInst, vd, vm); 1448 default: 1449 return new Unknown(machInst); 1450 } 1451 case 0x1: 1452 switch (bits(b, 3, 1)) { 1453 case 0x0: 1454 if (bits(b, 4)) { 1455 if (q) { 1456 return new NVcgtQFp<float>(machInst, vd, vm); 1457 } else { 1458 return new NVcgtDFp<float>(machInst, vd, vm); 1459 } 1460 } else { 1461 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 1462 q, size, machInst, vd, vm); 1463 } 1464 case 0x1: 1465 if (bits(b, 4)) { 1466 if (q) { 1467 return new NVcgeQFp<float>(machInst, vd, vm); 1468 } else { 1469 return new NVcgeDFp<float>(machInst, vd, vm); 1470 } 1471 } else { 1472 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 1473 q, size, machInst, vd, vm); 1474 } 1475 case 0x2: 1476 if (bits(b, 4)) { 1477 if (q) { 1478 return new NVceqQFp<float>(machInst, vd, vm); 1479 } else { 1480 return new NVceqDFp<float>(machInst, vd, vm); 1481 } 1482 } else { 1483 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 1484 q, size, machInst, vd, vm); 1485 } 1486 case 0x3: 1487 if (bits(b, 4)) { 1488 if (q) { 1489 return new NVcleQFp<float>(machInst, vd, vm); 1490 } else { 1491 return new NVcleDFp<float>(machInst, vd, vm); 1492 } 1493 } else { 1494 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 1495 q, size, machInst, vd, vm); 1496 } 1497 case 0x4: 1498 if (bits(b, 4)) { 1499 if (q) { 1500 return new NVcltQFp<float>(machInst, vd, vm); 1501 } else { 1502 return new NVcltDFp<float>(machInst, vd, vm); 1503 } 1504 } else { 1505 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 1506 q, size, machInst, vd, vm); 1507 } 1508 case 0x6: 1509 if (bits(machInst, 10)) { 1510 if (q) 1511 return new NVabsQFp<float>(machInst, vd, vm); 1512 else 1513 return new NVabsDFp<float>(machInst, vd, vm); 1514 } else { 1515 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 1516 q, size, machInst, vd, vm); 1517 } 1518 case 0x7: 1519 if (bits(machInst, 10)) { 1520 if (q) 1521 return new NVnegQFp<float>(machInst, vd, vm); 1522 else 1523 return new NVnegDFp<float>(machInst, vd, vm); 1524 } else { 1525 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 1526 q, size, machInst, vd, vm); 1527 } 1528 } 1529 case 0x2: 1530 switch (bits(b, 4, 1)) { 1531 case 0x0: 1532 if (q) 1533 return new NVswpQ<uint64_t>(machInst, vd, vm); 1534 else 1535 return new NVswpD<uint64_t>(machInst, vd, vm); 1536 case 0x1: 1537 return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>( 1538 q, size, machInst, vd, vm); 1539 case 0x2: 1540 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 1541 q, size, machInst, vd, vm); 1542 case 0x3: 1543 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 1544 q, size, machInst, vd, vm); 1545 case 0x4: 1546 if (b == 0x8) { 1547 return decodeNeonUTwoMiscUSReg<NVmovn>( 1548 size, machInst, vd, vm); 1549 } else { 1550 return decodeNeonSTwoMiscUSReg<NVqmovuns>( 1551 size, machInst, vd, vm); 1552 } 1553 case 0x5: 1554 if (q) { 1555 return decodeNeonUTwoMiscUSReg<NVqmovun>( 1556 size, machInst, vd, vm); 1557 } else { 1558 return decodeNeonSTwoMiscUSReg<NVqmovn>( 1559 size, machInst, vd, vm); 1560 } 1561 case 0x6: 1562 if (b == 0xc) { 1563 const IntRegIndex vd = 1564 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1565 (bits(machInst, 22) << 4))); 1566 const IntRegIndex vm = 1567 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1568 (bits(machInst, 5) << 4))); 1569 unsigned size = bits(machInst, 19, 18); 1570 return decodeNeonSTwoShiftUSReg<NVshll>( 1571 size, machInst, vd, vm, 8 << size); 1572 } else { 1573 return new Unknown(machInst); 1574 } 1575 case 0xc: 1576 case 0xe: 1577 if (b == 0x18) { 1578 if (size != 1 || (vm % 2)) 1579 return new Unknown(machInst); 1580 return new NVcvts2h<uint16_t>(machInst, vd, vm); 1581 } else if (b == 0x1c) { 1582 if (size != 1 || (vd % 2)) 1583 return new Unknown(machInst); 1584 return new NVcvth2s<uint16_t>(machInst, vd, vm); 1585 } else { 1586 return new Unknown(machInst); 1587 } 1588 default: 1589 return new Unknown(machInst); 1590 } 1591 case 0x3: 1592 if (bits(b, 4, 3) == 0x3) { 1593 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1594 return new Unknown(machInst); 1595 } else { 1596 if (bits(b, 2)) { 1597 if (bits(b, 1)) { 1598 if (q) { 1599 return new NVcvt2ufxQ<float>( 1600 machInst, vd, vm, 0); 1601 } else { 1602 return new NVcvt2ufxD<float>( 1603 machInst, vd, vm, 0); 1604 } 1605 } else { 1606 if (q) { 1607 return new NVcvt2sfxQ<float>( 1608 machInst, vd, vm, 0); 1609 } else { 1610 return new NVcvt2sfxD<float>( 1611 machInst, vd, vm, 0); 1612 } 1613 } 1614 } else { 1615 if (bits(b, 1)) { 1616 if (q) { 1617 return new NVcvtu2fpQ<float>( 1618 machInst, vd, vm, 0); 1619 } else { 1620 return new NVcvtu2fpD<float>( 1621 machInst, vd, vm, 0); 1622 } 1623 } else { 1624 if (q) { 1625 return new NVcvts2fpQ<float>( 1626 machInst, vd, vm, 0); 1627 } else { 1628 return new NVcvts2fpD<float>( 1629 machInst, vd, vm, 0); 1630 } 1631 } 1632 } 1633 } 1634 } else if ((b & 0x1a) == 0x10) { 1635 if (bits(b, 2)) { 1636 if (q) { 1637 return new NVrecpeQFp<float>(machInst, vd, vm); 1638 } else { 1639 return new NVrecpeDFp<float>(machInst, vd, vm); 1640 } 1641 } else { 1642 if (q) { 1643 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1644 } else { 1645 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1646 } 1647 } 1648 } else if ((b & 0x1a) == 0x12) { 1649 if (bits(b, 2)) { 1650 if (q) { 1651 return new NVrsqrteQFp<float>(machInst, vd, vm); 1652 } else { 1653 return new NVrsqrteDFp<float>(machInst, vd, vm); 1654 } 1655 } else { 1656 if (q) { 1657 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1658 } else { 1659 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1660 } 1661 } 1662 } else { 1663 return new Unknown(machInst); 1664 } 1665 } 1666 return new Unknown(machInst); 1667 } 1668 1669 StaticInstPtr 1670 decodeNeonData(ExtMachInst machInst) 1671 { 1672 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1673 const uint32_t a = bits(machInst, 23, 19); 1674 const uint32_t b = bits(machInst, 11, 8); 1675 const uint32_t c = bits(machInst, 7, 4); 1676 if (bits(a, 4) == 0) { 1677 return decodeNeonThreeRegistersSameLength(machInst); 1678 } else if ((c & 0x9) == 1) { 1679 if ((a & 0x7) == 0) { 1680 return decodeNeonOneRegModImm(machInst); 1681 } else { 1682 return decodeNeonTwoRegAndShift(machInst); 1683 } 1684 } else if ((c & 0x9) == 9) { 1685 return decodeNeonTwoRegAndShift(machInst); 1686 } else if (bits(a, 2, 1) != 0x3) { 1687 if ((c & 0x5) == 0) { 1688 return decodeNeonThreeRegDiffLengths(machInst); 1689 } else if ((c & 0x5) == 4) { 1690 return decodeNeonTwoRegScalar(machInst); 1691 } 1692 } else if ((a & 0x16) == 0x16) { 1693 const IntRegIndex vd = 1694 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1695 (bits(machInst, 22) << 4))); 1696 const IntRegIndex vn = 1697 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1698 (bits(machInst, 7) << 4))); 1699 const IntRegIndex vm = 1700 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1701 (bits(machInst, 5) << 4))); 1702 if (!u) { 1703 if (bits(c, 0) == 0) { 1704 unsigned imm4 = bits(machInst, 11, 8); 1705 bool q = bits(machInst, 6); 1706 if (imm4 >= 16 && !q) 1707 return new Unknown(machInst); 1708 if (q) { 1709 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1710 } else { 1711 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1712 } 1713 } 1714 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1715 return decodeNeonTwoRegMisc(machInst); 1716 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { 1717 unsigned length = bits(machInst, 9, 8) + 1; 1718 if ((uint32_t)vn / 2 + length > 32) 1719 return new Unknown(machInst); 1720 if (bits(machInst, 6) == 0) { 1721 switch (length) { 1722 case 1: 1723 return new NVtbl1(machInst, vd, vn, vm); 1724 case 2: 1725 return new NVtbl2(machInst, vd, vn, vm); 1726 case 3: 1727 return new NVtbl3(machInst, vd, vn, vm); 1728 case 4: 1729 return new NVtbl4(machInst, vd, vn, vm); 1730 } 1731 } else { 1732 switch (length) { 1733 case 1: 1734 return new NVtbx1(machInst, vd, vn, vm); 1735 case 2: 1736 return new NVtbx2(machInst, vd, vn, vm); 1737 case 3: 1738 return new NVtbx3(machInst, vd, vn, vm); 1739 case 4: 1740 return new NVtbx4(machInst, vd, vn, vm); 1741 } 1742 } 1743 } else if (b == 0xc && (c & 0x9) == 0) { 1744 unsigned imm4 = bits(machInst, 19, 16); 1745 if (bits(imm4, 2, 0) == 0) 1746 return new Unknown(machInst); 1747 unsigned size = 0; 1748 while ((imm4 & 0x1) == 0) { 1749 size++; 1750 imm4 >>= 1; 1751 } 1752 unsigned index = imm4 >> 1; 1753 const bool q = bits(machInst, 6); 1754 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1755 q, size, machInst, vd, vm, index); 1756 } 1757 } 1758 return new Unknown(machInst); 1759 } 1760 ''' 1761}}; 1762 1763def format ThumbNeonMem() {{ 1764 decode_block = ''' 1765 return decodeNeonMem(machInst); 1766 ''' 1767}}; 1768 1769def format ThumbNeonData() {{ 1770 decode_block = ''' 1771 return decodeNeonData(machInst); 1772 ''' 1773}}; 1774 1775let {{ 1776 header_output = ''' 1777 StaticInstPtr 1778 decodeExtensionRegLoadStore(ExtMachInst machInst); 1779 ''' 1780 decoder_output = ''' 1781 StaticInstPtr 1782 decodeExtensionRegLoadStore(ExtMachInst machInst) 1783 { 1784 const uint32_t opcode = bits(machInst, 24, 20); 1785 const uint32_t offset = bits(machInst, 7, 0); 1786 const bool single = (bits(machInst, 8) == 0); 1787 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1788 RegIndex vd; 1789 if (single) { 1790 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1791 bits(machInst, 22)); 1792 } else { 1793 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1794 (bits(machInst, 22) << 5)); 1795 } 1796 switch (bits(opcode, 4, 3)) { 1797 case 0x0: 1798 if (bits(opcode, 4, 1) == 0x2 && 1799 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1800 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1801 if ((bits(machInst, 7, 4) & 0xd) != 1) { 1802 break; 1803 } 1804 const IntRegIndex rt = 1805 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1806 const IntRegIndex rt2 = 1807 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1808 const bool op = bits(machInst, 20); 1809 uint32_t vm; 1810 if (single) { 1811 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1812 } else { 1813 vm = (bits(machInst, 3, 0) << 1) | 1814 (bits(machInst, 5) << 5); 1815 } 1816 if (op) { 1817 return new Vmov2Core2Reg(machInst, rt, rt2, 1818 (IntRegIndex)vm); 1819 } else { 1820 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1821 rt, rt2); 1822 } 1823 } 1824 break; 1825 case 0x1: 1826 { 1827 if (offset == 0 || vd + offset/2 > NumFloatArchRegs) { 1828 break; 1829 } 1830 switch (bits(opcode, 1, 0)) { 1831 case 0x0: 1832 return new VLdmStm(machInst, rn, vd, single, 1833 true, false, false, offset); 1834 case 0x1: 1835 return new VLdmStm(machInst, rn, vd, single, 1836 true, false, true, offset); 1837 case 0x2: 1838 return new VLdmStm(machInst, rn, vd, single, 1839 true, true, false, offset); 1840 case 0x3: 1841 // If rn == sp, then this is called vpop. 1842 return new VLdmStm(machInst, rn, vd, single, 1843 true, true, true, offset); 1844 } 1845 } 1846 case 0x2: 1847 if (bits(opcode, 1, 0) == 0x2) { 1848 // If rn == sp, then this is called vpush. 1849 return new VLdmStm(machInst, rn, vd, single, 1850 false, true, false, offset); 1851 } else if (bits(opcode, 1, 0) == 0x3) { 1852 return new VLdmStm(machInst, rn, vd, single, 1853 false, true, true, offset); 1854 } 1855 // Fall through on purpose 1856 case 0x3: 1857 const bool up = (bits(machInst, 23) == 1); 1858 const uint32_t imm = bits(machInst, 7, 0) << 2; 1859 RegIndex vd; 1860 if (single) { 1861 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1862 (bits(machInst, 22))); 1863 } else { 1864 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1865 (bits(machInst, 22) << 5)); 1866 } 1867 if (bits(opcode, 1, 0) == 0x0) { 1868 if (single) { 1869 if (up) { 1870 return new %(vstr_us)s(machInst, vd, rn, up, imm); 1871 } else { 1872 return new %(vstr_s)s(machInst, vd, rn, up, imm); 1873 } 1874 } else { 1875 if (up) { 1876 return new %(vstr_ud)s(machInst, vd, vd + 1, 1877 rn, up, imm); 1878 } else { 1879 return new %(vstr_d)s(machInst, vd, vd + 1, 1880 rn, up, imm); 1881 } 1882 } 1883 } else if (bits(opcode, 1, 0) == 0x1) { 1884 if (single) { 1885 if (up) { 1886 return new %(vldr_us)s(machInst, vd, rn, up, imm); 1887 } else { 1888 return new %(vldr_s)s(machInst, vd, rn, up, imm); 1889 } 1890 } else { 1891 if (up) { 1892 return new %(vldr_ud)s(machInst, vd, vd + 1, 1893 rn, up, imm); 1894 } else { 1895 return new %(vldr_d)s(machInst, vd, vd + 1, 1896 rn, up, imm); 1897 } 1898 } 1899 } 1900 } 1901 return new Unknown(machInst); 1902 } 1903 ''' % { 1904 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 1905 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 1906 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 1907 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 1908 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 1909 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 1910 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 1911 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 1912 } 1913}}; 1914 1915def format ExtensionRegLoadStore() {{ 1916 decode_block = ''' 1917 return decodeExtensionRegLoadStore(machInst); 1918 ''' 1919}}; 1920 1921let {{ 1922 header_output = ''' 1923 StaticInstPtr 1924 decodeShortFpTransfer(ExtMachInst machInst); 1925 ''' 1926 decoder_output = ''' 1927 StaticInstPtr 1928 decodeShortFpTransfer(ExtMachInst machInst) 1929 { 1930 const uint32_t l = bits(machInst, 20); 1931 const uint32_t c = bits(machInst, 8); 1932 const uint32_t a = bits(machInst, 23, 21); 1933 const uint32_t b = bits(machInst, 6, 5); 1934 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 1935 (machInst.thumb == 0 && machInst.condCode == 0xf)) { 1936 return new Unknown(machInst); 1937 } 1938 if (l == 0 && c == 0) { 1939 if (a == 0) { 1940 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 1941 bits(machInst, 7); 1942 const IntRegIndex rt = 1943 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1944 if (bits(machInst, 20) == 1) { 1945 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 1946 } else { 1947 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 1948 } 1949 } else if (a == 0x7) { 1950 const IntRegIndex rt = 1951 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1952 uint32_t specReg = bits(machInst, 19, 16); 1953 switch (specReg) { 1954 case 0: 1955 specReg = MISCREG_FPSID; 1956 break; 1957 case 1: 1958 specReg = MISCREG_FPSCR; 1959 break; 1960 case 6: 1961 specReg = MISCREG_MVFR1; 1962 break; 1963 case 7: 1964 specReg = MISCREG_MVFR0; 1965 break; 1966 case 8: 1967 specReg = MISCREG_FPEXC; 1968 break; 1969 default: 1970 return new Unknown(machInst); 1971 } 1972 if (specReg == MISCREG_FPSCR) { 1973 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 1974 } else { 1975 return new Vmsr(machInst, (IntRegIndex)specReg, rt); 1976 } 1977 } 1978 } else if (l == 0 && c == 1) { 1979 if (bits(a, 2) == 0) { 1980 uint32_t vd = (bits(machInst, 7) << 5) | 1981 (bits(machInst, 19, 16) << 1); 1982 // Handle accessing each single precision half of the vector. 1983 vd += bits(machInst, 21); 1984 const IntRegIndex rt = 1985 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1986 if (bits(machInst, 22) == 1) { 1987 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 1988 rt, bits(machInst, 6, 5)); 1989 } else if (bits(machInst, 5) == 1) { 1990 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 1991 rt, bits(machInst, 6)); 1992 } else if (bits(machInst, 6) == 0) { 1993 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 1994 } else { 1995 return new Unknown(machInst); 1996 } 1997 } else if (bits(b, 1) == 0) { 1998 bool q = bits(machInst, 21); 1999 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2000 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2001 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2002 IntRegIndex rt = (IntRegIndex)(uint32_t) 2003 bits(machInst, 15, 12); 2004 if (q) { 2005 switch (be) { 2006 case 0: 2007 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2008 case 1: 2009 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2010 case 2: 2011 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2012 case 3: 2013 return new Unknown(machInst); 2014 } 2015 } else { 2016 switch (be) { 2017 case 0: 2018 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2019 case 1: 2020 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2021 case 2: 2022 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2023 case 3: 2024 return new Unknown(machInst); 2025 } 2026 } 2027 } 2028 } else if (l == 1 && c == 0) { 2029 if (a == 0) { 2030 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2031 bits(machInst, 7); 2032 const IntRegIndex rt = 2033 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2034 if (bits(machInst, 20) == 1) { 2035 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2036 } else { 2037 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2038 } 2039 } else if (a == 7) { 2040 const IntRegIndex rt = 2041 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2042 uint32_t specReg = bits(machInst, 19, 16); 2043 switch (specReg) { 2044 case 0: 2045 specReg = MISCREG_FPSID; 2046 break; 2047 case 1: 2048 specReg = MISCREG_FPSCR; 2049 break; 2050 case 6: 2051 specReg = MISCREG_MVFR1; 2052 break; 2053 case 7: 2054 specReg = MISCREG_MVFR0; 2055 break; 2056 case 8: 2057 specReg = MISCREG_FPEXC; 2058 break; 2059 default: 2060 return new Unknown(machInst); 2061 } 2062 if (rt == 0xf) { 2063 CPSR cpsrMask = 0; 2064 cpsrMask.n = 1; 2065 cpsrMask.z = 1; 2066 cpsrMask.c = 1; 2067 cpsrMask.v = 1; 2068 if (specReg == MISCREG_FPSCR) { 2069 return new VmrsApsrFpscr(machInst, INTREG_CONDCODES, 2070 (IntRegIndex)specReg, (uint32_t)cpsrMask); 2071 } else { 2072 return new VmrsApsr(machInst, INTREG_CONDCODES, 2073 (IntRegIndex)specReg, (uint32_t)cpsrMask); 2074 } 2075 } else if (specReg == MISCREG_FPSCR) { 2076 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2077 } else { 2078 return new Vmrs(machInst, rt, (IntRegIndex)specReg); 2079 } 2080 } 2081 } else { 2082 uint32_t vd = (bits(machInst, 7) << 5) | 2083 (bits(machInst, 19, 16) << 1); 2084 // Handle indexing into each single precision half of the vector. 2085 vd += bits(machInst, 21); 2086 uint32_t index; 2087 const IntRegIndex rt = 2088 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2089 const bool u = (bits(machInst, 23) == 1); 2090 if (bits(machInst, 22) == 1) { 2091 index = bits(machInst, 6, 5); 2092 if (u) { 2093 return new VmovRegCoreUB(machInst, rt, 2094 (IntRegIndex)vd, index); 2095 } else { 2096 return new VmovRegCoreSB(machInst, rt, 2097 (IntRegIndex)vd, index); 2098 } 2099 } else if (bits(machInst, 5) == 1) { 2100 index = bits(machInst, 6); 2101 if (u) { 2102 return new VmovRegCoreUH(machInst, rt, 2103 (IntRegIndex)vd, index); 2104 } else { 2105 return new VmovRegCoreSH(machInst, rt, 2106 (IntRegIndex)vd, index); 2107 } 2108 } else if (bits(machInst, 6) == 0 && !u) { 2109 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2110 } else { 2111 return new Unknown(machInst); 2112 } 2113 } 2114 return new Unknown(machInst); 2115 } 2116 ''' 2117}}; 2118 2119def format ShortFpTransfer() {{ 2120 decode_block = ''' 2121 return decodeShortFpTransfer(machInst); 2122 ''' 2123}}; 2124 2125let {{ 2126 header_output = ''' 2127 StaticInstPtr 2128 decodeVfpData(ExtMachInst machInst); 2129 ''' 2130 decoder_output = ''' 2131 StaticInstPtr 2132 decodeVfpData(ExtMachInst machInst) 2133 { 2134 const uint32_t opc1 = bits(machInst, 23, 20); 2135 const uint32_t opc2 = bits(machInst, 19, 16); 2136 const uint32_t opc3 = bits(machInst, 7, 6); 2137 //const uint32_t opc4 = bits(machInst, 3, 0); 2138 const bool single = (bits(machInst, 8) == 0); 2139 // Used to select between vcmp and vcmpe. 2140 const bool e = (bits(machInst, 7) == 1); 2141 IntRegIndex vd; 2142 IntRegIndex vm; 2143 IntRegIndex vn; 2144 if (single) { 2145 vd = (IntRegIndex)(bits(machInst, 22) | 2146 (bits(machInst, 15, 12) << 1)); 2147 vm = (IntRegIndex)(bits(machInst, 5) | 2148 (bits(machInst, 3, 0) << 1)); 2149 vn = (IntRegIndex)(bits(machInst, 7) | 2150 (bits(machInst, 19, 16) << 1)); 2151 } else { 2152 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2153 (bits(machInst, 15, 12) << 1)); 2154 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2155 (bits(machInst, 3, 0) << 1)); 2156 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2157 (bits(machInst, 19, 16) << 1)); 2158 } 2159 switch (opc1 & 0xb /* 1011 */) { 2160 case 0x0: 2161 if (bits(machInst, 6) == 0) { 2162 if (single) { 2163 return decodeVfpRegRegRegOp<VmlaS>( 2164 machInst, vd, vn, vm, false); 2165 } else { 2166 return decodeVfpRegRegRegOp<VmlaD>( 2167 machInst, vd, vn, vm, true); 2168 } 2169 } else { 2170 if (single) { 2171 return decodeVfpRegRegRegOp<VmlsS>( 2172 machInst, vd, vn, vm, false); 2173 } else { 2174 return decodeVfpRegRegRegOp<VmlsD>( 2175 machInst, vd, vn, vm, true); 2176 } 2177 } 2178 case 0x1: 2179 if (bits(machInst, 6) == 1) { 2180 if (single) { 2181 return decodeVfpRegRegRegOp<VnmlaS>( 2182 machInst, vd, vn, vm, false); 2183 } else { 2184 return decodeVfpRegRegRegOp<VnmlaD>( 2185 machInst, vd, vn, vm, true); 2186 } 2187 } else { 2188 if (single) { 2189 return decodeVfpRegRegRegOp<VnmlsS>( 2190 machInst, vd, vn, vm, false); 2191 } else { 2192 return decodeVfpRegRegRegOp<VnmlsD>( 2193 machInst, vd, vn, vm, true); 2194 } 2195 } 2196 case 0x2: 2197 if ((opc3 & 0x1) == 0) { 2198 if (single) { 2199 return decodeVfpRegRegRegOp<VmulS>( 2200 machInst, vd, vn, vm, false); 2201 } else { 2202 return decodeVfpRegRegRegOp<VmulD>( 2203 machInst, vd, vn, vm, true); 2204 } 2205 } else { 2206 if (single) { 2207 return decodeVfpRegRegRegOp<VnmulS>( 2208 machInst, vd, vn, vm, false); 2209 } else { 2210 return decodeVfpRegRegRegOp<VnmulD>( 2211 machInst, vd, vn, vm, true); 2212 } 2213 } 2214 case 0x3: 2215 if ((opc3 & 0x1) == 0) { 2216 if (single) { 2217 return decodeVfpRegRegRegOp<VaddS>( 2218 machInst, vd, vn, vm, false); 2219 } else { 2220 return decodeVfpRegRegRegOp<VaddD>( 2221 machInst, vd, vn, vm, true); 2222 } 2223 } else { 2224 if (single) { 2225 return decodeVfpRegRegRegOp<VsubS>( 2226 machInst, vd, vn, vm, false); 2227 } else { 2228 return decodeVfpRegRegRegOp<VsubD>( 2229 machInst, vd, vn, vm, true); 2230 } 2231 } 2232 case 0x8: 2233 if ((opc3 & 0x1) == 0) { 2234 if (single) { 2235 return decodeVfpRegRegRegOp<VdivS>( 2236 machInst, vd, vn, vm, false); 2237 } else { 2238 return decodeVfpRegRegRegOp<VdivD>( 2239 machInst, vd, vn, vm, true); 2240 } 2241 } 2242 break; 2243 case 0xb: 2244 if ((opc3 & 0x1) == 0) { 2245 const uint32_t baseImm = 2246 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2247 if (single) { 2248 uint32_t imm = vfp_modified_imm(baseImm, false); 2249 return decodeVfpRegImmOp<VmovImmS>( 2250 machInst, vd, imm, false); 2251 } else { 2252 uint64_t imm = vfp_modified_imm(baseImm, true); 2253 return decodeVfpRegImmOp<VmovImmD>( 2254 machInst, vd, imm, true); 2255 } 2256 } 2257 switch (opc2) { 2258 case 0x0: 2259 if (opc3 == 1) { 2260 if (single) { 2261 return decodeVfpRegRegOp<VmovRegS>( 2262 machInst, vd, vm, false); 2263 } else { 2264 return decodeVfpRegRegOp<VmovRegD>( 2265 machInst, vd, vm, true); 2266 } 2267 } else { 2268 if (single) { 2269 return decodeVfpRegRegOp<VabsS>( 2270 machInst, vd, vm, false); 2271 } else { 2272 return decodeVfpRegRegOp<VabsD>( 2273 machInst, vd, vm, true); 2274 } 2275 } 2276 case 0x1: 2277 if (opc3 == 1) { 2278 if (single) { 2279 return decodeVfpRegRegOp<VnegS>( 2280 machInst, vd, vm, false); 2281 } else { 2282 return decodeVfpRegRegOp<VnegD>( 2283 machInst, vd, vm, true); 2284 } 2285 } else { 2286 if (single) { 2287 return decodeVfpRegRegOp<VsqrtS>( 2288 machInst, vd, vm, false); 2289 } else { 2290 return decodeVfpRegRegOp<VsqrtD>( 2291 machInst, vd, vm, true); 2292 } 2293 } 2294 case 0x2: 2295 case 0x3: 2296 { 2297 const bool toHalf = bits(machInst, 16); 2298 const bool top = bits(machInst, 7); 2299 if (top) { 2300 if (toHalf) { 2301 return new VcvtFpSFpHT(machInst, vd, vm); 2302 } else { 2303 return new VcvtFpHTFpS(machInst, vd, vm); 2304 } 2305 } else { 2306 if (toHalf) { 2307 return new VcvtFpSFpHB(machInst, vd, vm); 2308 } else { 2309 return new VcvtFpHBFpS(machInst, vd, vm); 2310 } 2311 } 2312 } 2313 case 0x4: 2314 if (single) { 2315 if (e) { 2316 return new VcmpeS(machInst, vd, vm); 2317 } else { 2318 return new VcmpS(machInst, vd, vm); 2319 } 2320 } else { 2321 if (e) { 2322 return new VcmpeD(machInst, vd, vm); 2323 } else { 2324 return new VcmpD(machInst, vd, vm); 2325 } 2326 } 2327 case 0x5: 2328 if (single) { 2329 if (e) { 2330 return new VcmpeZeroS(machInst, vd, 0); 2331 } else { 2332 return new VcmpZeroS(machInst, vd, 0); 2333 } 2334 } else { 2335 if (e) { 2336 return new VcmpeZeroD(machInst, vd, 0); 2337 } else { 2338 return new VcmpZeroD(machInst, vd, 0); 2339 } 2340 } 2341 case 0x7: 2342 if (opc3 == 0x3) { 2343 if (single) { 2344 vm = (IntRegIndex)(bits(machInst, 5) | 2345 (bits(machInst, 3, 0) << 1)); 2346 return new VcvtFpSFpD(machInst, vd, vm); 2347 } else { 2348 vd = (IntRegIndex)(bits(machInst, 22) | 2349 (bits(machInst, 15, 12) << 1)); 2350 return new VcvtFpDFpS(machInst, vd, vm); 2351 } 2352 } 2353 break; 2354 case 0x8: 2355 if (bits(machInst, 7) == 0) { 2356 if (single) { 2357 return new VcvtUIntFpS(machInst, vd, vm); 2358 } else { 2359 vm = (IntRegIndex)(bits(machInst, 5) | 2360 (bits(machInst, 3, 0) << 1)); 2361 return new VcvtUIntFpD(machInst, vd, vm); 2362 } 2363 } else { 2364 if (single) { 2365 return new VcvtSIntFpS(machInst, vd, vm); 2366 } else { 2367 vm = (IntRegIndex)(bits(machInst, 5) | 2368 (bits(machInst, 3, 0) << 1)); 2369 return new VcvtSIntFpD(machInst, vd, vm); 2370 } 2371 } 2372 case 0xa: 2373 { 2374 const bool half = (bits(machInst, 7) == 0); 2375 const uint32_t imm = bits(machInst, 5) | 2376 (bits(machInst, 3, 0) << 1); 2377 const uint32_t size = 2378 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2379 if (single) { 2380 if (half) { 2381 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2382 } else { 2383 return new VcvtSFixedFpS(machInst, vd, vd, size); 2384 } 2385 } else { 2386 if (half) { 2387 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2388 } else { 2389 return new VcvtSFixedFpD(machInst, vd, vd, size); 2390 } 2391 } 2392 } 2393 case 0xb: 2394 { 2395 const bool half = (bits(machInst, 7) == 0); 2396 const uint32_t imm = bits(machInst, 5) | 2397 (bits(machInst, 3, 0) << 1); 2398 const uint32_t size = 2399 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2400 if (single) { 2401 if (half) { 2402 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2403 } else { 2404 return new VcvtUFixedFpS(machInst, vd, vd, size); 2405 } 2406 } else { 2407 if (half) { 2408 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2409 } else { 2410 return new VcvtUFixedFpD(machInst, vd, vd, size); 2411 } 2412 } 2413 } 2414 case 0xc: 2415 if (bits(machInst, 7) == 0) { 2416 if (single) { 2417 return new VcvtFpUIntSR(machInst, vd, vm); 2418 } else { 2419 vd = (IntRegIndex)(bits(machInst, 22) | 2420 (bits(machInst, 15, 12) << 1)); 2421 return new VcvtFpUIntDR(machInst, vd, vm); 2422 } 2423 } else { 2424 if (single) { 2425 return new VcvtFpUIntS(machInst, vd, vm); 2426 } else { 2427 vd = (IntRegIndex)(bits(machInst, 22) | 2428 (bits(machInst, 15, 12) << 1)); 2429 return new VcvtFpUIntD(machInst, vd, vm); 2430 } 2431 } 2432 case 0xd: 2433 if (bits(machInst, 7) == 0) { 2434 if (single) { 2435 return new VcvtFpSIntSR(machInst, vd, vm); 2436 } else { 2437 vd = (IntRegIndex)(bits(machInst, 22) | 2438 (bits(machInst, 15, 12) << 1)); 2439 return new VcvtFpSIntDR(machInst, vd, vm); 2440 } 2441 } else { 2442 if (single) { 2443 return new VcvtFpSIntS(machInst, vd, vm); 2444 } else { 2445 vd = (IntRegIndex)(bits(machInst, 22) | 2446 (bits(machInst, 15, 12) << 1)); 2447 return new VcvtFpSIntD(machInst, vd, vm); 2448 } 2449 } 2450 case 0xe: 2451 { 2452 const bool half = (bits(machInst, 7) == 0); 2453 const uint32_t imm = bits(machInst, 5) | 2454 (bits(machInst, 3, 0) << 1); 2455 const uint32_t size = 2456 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2457 if (single) { 2458 if (half) { 2459 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2460 } else { 2461 return new VcvtFpSFixedS(machInst, vd, vd, size); 2462 } 2463 } else { 2464 if (half) { 2465 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2466 } else { 2467 return new VcvtFpSFixedD(machInst, vd, vd, size); 2468 } 2469 } 2470 } 2471 case 0xf: 2472 { 2473 const bool half = (bits(machInst, 7) == 0); 2474 const uint32_t imm = bits(machInst, 5) | 2475 (bits(machInst, 3, 0) << 1); 2476 const uint32_t size = 2477 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2478 if (single) { 2479 if (half) { 2480 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2481 } else { 2482 return new VcvtFpUFixedS(machInst, vd, vd, size); 2483 } 2484 } else { 2485 if (half) { 2486 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2487 } else { 2488 return new VcvtFpUFixedD(machInst, vd, vd, size); 2489 } 2490 } 2491 } 2492 } 2493 break; 2494 } 2495 return new Unknown(machInst); 2496 } 2497 ''' 2498}}; 2499 2500def format VfpData() {{ 2501 decode_block = ''' 2502 return decodeVfpData(machInst); 2503 ''' 2504}}; 2505