fp.isa revision 8303
19814Sandreas.hansson@arm.com// -*- mode:c++ -*- 22292SN/A 310333Smitch.hayenga@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: 824319Sktlim@umich.edu return new Base<uint16_t>(machInst, dest, op1, step); 832678Sktlim@umich.edu case 2: 842678Sktlim@umich.edu return new Base<uint32_t>(machInst, dest, op1, step); 852292SN/A case 3: 862678Sktlim@umich.edu return new Base<uint64_t>(machInst, dest, op1, step); 872678Sktlim@umich.edu default: 885336Shines@cs.fsu.edu panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 892678Sktlim@umich.edu } 904873Sstever@eecs.umich.edu } 912678Sktlim@umich.edu 922292SN/A}}; 932678Sktlim@umich.edu 942678Sktlim@umich.edulet {{ 952678Sktlim@umich.edu header_output = ''' 962678Sktlim@umich.edu StaticInstPtr 972678Sktlim@umich.edu decodeNeonMem(ExtMachInst machInst); 982678Sktlim@umich.edu 997852SMatt.Horsnell@arm.com StaticInstPtr 1007852SMatt.Horsnell@arm.com decodeNeonData(ExtMachInst machInst); 1012344SN/A ''' 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); 10910333Smitch.hayenga@arm.com const bool singleAll = single && (bits(b, 3, 2) == 3); 11010333Smitch.hayenga@arm.com const bool load = bits(machInst, 21); 11110333Smitch.hayenga@arm.com 1122678Sktlim@umich.edu unsigned width = 0; 1136974Stjones1@inf.ed.ac.uk 1146974Stjones1@inf.ed.ac.uk if (single) { 1156974Stjones1@inf.ed.ac.uk width = bits(b, 1, 0) + 1; 1166974Stjones1@inf.ed.ac.uk } else { 1176974Stjones1@inf.ed.ac.uk switch (bits(b, 3, 1)) { 1186974Stjones1@inf.ed.ac.uk case 0x0: width = 4; 1196974Stjones1@inf.ed.ac.uk break; 1209444SAndreas.Sandberg@ARM.com case 0x1: width = (b & 0x1) ? 2 : 1; 12110327Smitch.hayenga@arm.com break; 1222678Sktlim@umich.edu 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; 1276974Stjones1@inf.ed.ac.uk break; 1286974Stjones1@inf.ed.ac.uk case 0x5: 1292678Sktlim@umich.edu if ((b & 0x1) == 0) { 1302678Sktlim@umich.edu width = 1; 1312678Sktlim@umich.edu break; 1322678Sktlim@umich.edu } 1332678Sktlim@umich.edu // Fall through on purpose. 1342344SN/A default: 1352307SN/A return new Unknown(machInst); 1366974Stjones1@inf.ed.ac.uk } 1376974Stjones1@inf.ed.ac.uk } 1386974Stjones1@inf.ed.ac.uk assert(width > 0 && width <= 4); 1396974Stjones1@inf.ed.ac.uk 14010020Smatt.horsnell@ARM.com const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0); 14110020Smatt.horsnell@ARM.com const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16); 14210023Smatt.horsnell@ARM.com const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) | 14310023Smatt.horsnell@ARM.com bits(machInst, 22) << 4); 1442678Sktlim@umich.edu const uint32_t type = bits(machInst, 11, 8); 1454032Sktlim@umich.edu uint32_t size = 0; 1462678Sktlim@umich.edu uint32_t align = TLB::MustBeOne; 1472292SN/A unsigned inc = 1; 1482292SN/A unsigned regs = 1; 1492292SN/A unsigned lane = 0; 1502292SN/A if (single) { 1518545Ssaidi@eecs.umich.edu if (singleAll) { 15210333Smitch.hayenga@arm.com size = bits(machInst, 7, 6); 1532292SN/A bool t = bits(machInst, 5); 1542292SN/A unsigned eBytes = (1 << size); 1552292SN/A align = (eBytes - 1) | TLB::AllowUnaligned; 1562292SN/A if (width == 1) { 1572292SN/A regs = t ? 2 : 1; 1585529Snate@binkert.org inc = 1; 1595529Snate@binkert.org } else { 1605529Snate@binkert.org regs = width; 1612292SN/A inc = t ? 2 : 1; 1624329Sktlim@umich.edu } 1634329Sktlim@umich.edu switch (width) { 1644329Sktlim@umich.edu case 1: 1652907Sktlim@umich.edu case 2: 1662907Sktlim@umich.edu if (bits(machInst, 4)) 1672292SN/A align = width * eBytes - 1; 1682292SN/A break; 16910175SMitch.Hayenga@ARM.com case 3: 17010175SMitch.Hayenga@ARM.com break; 1712329SN/A case 4: 1722329SN/A if (size == 3) { 1732329SN/A if (bits(machInst, 4) == 0) 1742292SN/A return new Unknown(machInst); 1759936SFaissal.Sleiman@arm.com size = 2; 1769936SFaissal.Sleiman@arm.com align = 0xf; 1779936SFaissal.Sleiman@arm.com } else if (size == 2) { 1789936SFaissal.Sleiman@arm.com if (bits(machInst, 4)) 1792292SN/A align = 7; 1802292SN/A } else { 1812292SN/A if (bits(machInst, 4)) 1828199SAli.Saidi@ARM.com align = 4 * eBytes - 1; 1838199SAli.Saidi@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); 1929444SAndreas.Sandberg@ARM.com // If width is 1, inc is always 1. That's overridden later. 1939444SAndreas.Sandberg@ARM.com switch (size) { 1949444SAndreas.Sandberg@ARM.com case 0: 1959444SAndreas.Sandberg@ARM.com inc = 1; 1968199SAli.Saidi@ARM.com lane = bits(indexAlign, 3, 1); 1972292SN/A break; 1982292SN/A case 1: 1992292SN/A inc = bits(indexAlign, 1) ? 2 : 1; 2002292SN/A lane = bits(indexAlign, 3, 2); 2012292SN/A break; 2022292SN/A case 2: 2033492Sktlim@umich.edu inc = bits(indexAlign, 2) ? 2 : 1; 2042329SN/A lane = bits(indexAlign, 3); 2052292SN/A break; 2069444SAndreas.Sandberg@ARM.com } 2079444SAndreas.Sandberg@ARM.com // Override inc for width of 1. 2089814Sandreas.hansson@arm.com if (width == 1) { 2092292SN/A inc = 1; 2102292SN/A } 2112292SN/A switch (width) { 2122292SN/A case 1: 2132292SN/A switch (size) { 2142292SN/A case 0: 2152292SN/A break; 2162292SN/A case 1: 2172292SN/A if (bits(indexAlign, 0)) 2188247Snate@binkert.org align = 1; 2192292SN/A break; 2202292SN/A case 2: 2212292SN/A if (bits(indexAlign, 1, 0)) 2222292SN/A align = 3; 2232292SN/A 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; 2382727Sktlim@umich.edu break; 2392727Sktlim@umich.edu case 2: 2402727Sktlim@umich.edu if (bits(indexAlign, 0)) 2412727Sktlim@umich.edu align = (4 << bits(indexAlign, 1, 0)) - 1; 2422361SN/A break; 2432361SN/A } 2442361SN/A break; 2452361SN/A } 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; 2652727Sktlim@umich.edu break; 2662727Sktlim@umich.edu case 0x6: regs = 3; 2672727Sktlim@umich.edu break; 2682727Sktlim@umich.edu case 0x2: regs = 4; 2698922Swilliam.wang@arm.com break; 2704329Sktlim@umich.edu default: 2714329Sktlim@umich.edu return new Unknown(machInst); 2724329Sktlim@umich.edu } 2734329Sktlim@umich.edu break; 2744329Sktlim@umich.edu case 2: 2754329Sktlim@umich.edu // 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: 2862292SN/A return new Unknown(machInst); 2872292SN/A } 2882292SN/A break; 2892292SN/A case 3: 2909444SAndreas.Sandberg@ARM.com regs = 3; 2912307SN/A switch (type) { 2929444SAndreas.Sandberg@ARM.com case 0x4: inc = 1; 2932367SN/A break; 2942307SN/A case 0x5: inc = 2;; 2952329SN/A break; 2969444SAndreas.Sandberg@ARM.com default: 2972307SN/A return new Unknown(machInst); 2982307SN/A } 2992307SN/A break; 3002307SN/A case 4: 3012307SN/A regs = 4; 3022307SN/A switch (type) { 3039444SAndreas.Sandberg@ARM.com case 0: inc = 1; 3042307SN/A break; 3052307SN/A case 1: inc = 2; 3062307SN/A break; 3072307SN/A default: 3082292SN/A return new Unknown(machInst); 3092292SN/A } 3102329SN/A break; 3112329SN/A } 3122292SN/A } 3132329SN/A 3142329SN/A if (load) { 3152292SN/A // Load instructions. 3162292SN/A if (single) { 3172292SN/A return new VldSingle(machInst, singleAll, width, rn, vd, 3182292SN/A regs, inc, size, align, rm, lane); 3192292SN/A } else { 3202329SN/A return new VldMult(machInst, width, rn, vd, 3212292SN/A regs, inc, size, align, rm); 3222292SN/A } 3239936SFaissal.Sleiman@arm.com } else { 3242292SN/A // Store instructions. 3252292SN/A if (single) { 3262292SN/A if (singleAll) { 3272292SN/A return new Unknown(machInst); 3282292SN/A } else { 3292292SN/A return new VstSingle(machInst, false, width, rn, vd, 3302329SN/A regs, inc, size, align, rm, lane); 3312329SN/A } 3322329SN/A } else { 3332292SN/A return new VstMult(machInst, width, rn, vd, 3342292SN/A regs, inc, size, align, rm); 3352292SN/A } 3362292SN/A } 3372292SN/A return new Unknown(machInst); 3382329SN/A } 3392292SN/A ''' 3409936SFaissal.Sleiman@arm.com 3419936SFaissal.Sleiman@arm.com 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))) 3612292SN/A return new Unknown(machInst); 3622292SN/A switch (a) { 3632292SN/A case 0x0: 3642292SN/A if (b) { 3652329SN/A if (u) { 3662329SN/A return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 3672292SN/A q, size, machInst, vd, vn, vm); 3687720Sgblack@eecs.umich.edu } else { 3697720Sgblack@eecs.umich.edu 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); 3902292SN/A } 3912292SN/A case 1: 3922292SN/A if (q) { 3932292SN/A return new VbslQ<uint64_t>(machInst, vd, vn, vm); 3947720Sgblack@eecs.umich.edu } else { 3957720Sgblack@eecs.umich.edu 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 { 4162292SN/A return new VandD<uint64_t>(machInst, vd, vn, vm); 4172292SN/A } 4182292SN/A case 1: 4192292SN/A if (q) { 42010239Sbinhpham@cs.rutgers.edu return new VbicQ<uint64_t>(machInst, vd, vn, vm); 4212292SN/A } else { 42210239Sbinhpham@cs.rutgers.edu return new VbicD<uint64_t>(machInst, vd, vn, vm); 42310239Sbinhpham@cs.rutgers.edu } 42410239Sbinhpham@cs.rutgers.edu case 2: 42510239Sbinhpham@cs.rutgers.edu if (vn == vm) { 42610239Sbinhpham@cs.rutgers.edu if (q) { 4272292SN/A 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 { 43410239Sbinhpham@cs.rutgers.edu if (q) { 43510239Sbinhpham@cs.rutgers.edu return new VorrQ<uint64_t>( 43610239Sbinhpham@cs.rutgers.edu machInst, vd, vn, vm); 43710239Sbinhpham@cs.rutgers.edu } else { 4382292SN/A return new VorrD<uint64_t>( 4392292SN/A machInst, vd, vn, vm); 4408545Ssaidi@eecs.umich.edu } 4418545Ssaidi@eecs.umich.edu } 4428545Ssaidi@eecs.umich.edu case 3: 4438545Ssaidi@eecs.umich.edu if (q) { 44410030SAli.Saidi@ARM.com return new VornQ<uint64_t>( 4458545Ssaidi@eecs.umich.edu machInst, vd, vn, vm); 4469383SAli.Saidi@ARM.com } else { 4479383SAli.Saidi@ARM.com return new VornD<uint64_t>( 4489383SAli.Saidi@ARM.com machInst, vd, vn, vm); 4499383SAli.Saidi@ARM.com } 45010030SAli.Saidi@ARM.com } 4519383SAli.Saidi@ARM.com } 4529383SAli.Saidi@ARM.com } 4539383SAli.Saidi@ARM.com case 0x2: 4549383SAli.Saidi@ARM.com if (b) { 4559383SAli.Saidi@ARM.com if (u) { 4569383SAli.Saidi@ARM.com return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 4579383SAli.Saidi@ARM.com q, size, machInst, vd, vn, vm); 45810030SAli.Saidi@ARM.com } else { 45910030SAli.Saidi@ARM.com return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 46010030SAli.Saidi@ARM.com q, size, machInst, vd, vn, vm); 46110030SAli.Saidi@ARM.com } 46210030SAli.Saidi@ARM.com } else { 46310030SAli.Saidi@ARM.com if (size == 3) 46410030SAli.Saidi@ARM.com return new Unknown(machInst); 46510030SAli.Saidi@ARM.com 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>( 4809046SAli.Saidi@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 } 4858545Ssaidi@eecs.umich.edu } else { 4868545Ssaidi@eecs.umich.edu return decodeNeonUSThreeReg<VshlD, VshlQ>( 4878545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vm, vn); 4888545Ssaidi@eecs.umich.edu } 48910149Smarco.elver@ed.ac.uk case 0x5: 49010149Smarco.elver@ed.ac.uk if (b) { 49110149Smarco.elver@ed.ac.uk if (u) { 49210149Smarco.elver@ed.ac.uk 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); 4978545Ssaidi@eecs.umich.edu } 49810030SAli.Saidi@ARM.com } else { 4998545Ssaidi@eecs.umich.edu return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 5008545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vm, vn); 5018545Ssaidi@eecs.umich.edu } 5028545Ssaidi@eecs.umich.edu case 0x6: 50310030SAli.Saidi@ARM.com if (b) { 50410030SAli.Saidi@ARM.com return decodeNeonUSThreeReg<VminD, VminQ>( 50510030SAli.Saidi@ARM.com 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) { 5128545Ssaidi@eecs.umich.edu return decodeNeonUSThreeReg<VabaD, VabaQ>( 5138545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5148545Ssaidi@eecs.umich.edu } else { 5159046SAli.Saidi@ARM.com if (bits(machInst, 23) == 1) { 5168545Ssaidi@eecs.umich.edu if (q) { 5178545Ssaidi@eecs.umich.edu return new Unknown(machInst); 5188545Ssaidi@eecs.umich.edu } 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>( 5242292SN/A q, u, size, machInst, vd, vn, vm); 5258199SAli.Saidi@ARM.com } 5268199SAli.Saidi@ARM.com } 5278199SAli.Saidi@ARM.com 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 { 5379046SAli.Saidi@ARM.com if (u) { 5388199SAli.Saidi@ARM.com return decodeNeonUThreeReg<NVsubD, NVsubQ>( 5398199SAli.Saidi@ARM.com q, size, machInst, vd, vn, vm); 5408199SAli.Saidi@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: 5468272SAli.Saidi@ARM.com if (b) { 5478545Ssaidi@eecs.umich.edu if (u) { 5488545Ssaidi@eecs.umich.edu return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 5498545Ssaidi@eecs.umich.edu q, size, machInst, vd, vn, vm); 5508545Ssaidi@eecs.umich.edu } else { 5519046SAli.Saidi@ARM.com return decodeNeonSThreeReg<NVmulD, NVmulQ>( 5528545Ssaidi@eecs.umich.edu q, size, machInst, vd, vn, vm); 5538545Ssaidi@eecs.umich.edu } 5548545Ssaidi@eecs.umich.edu } else { 5558592Sgblack@eecs.umich.edu if (u) { 5568592Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 5578545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5588199SAli.Saidi@ARM.com } else { 5598545Ssaidi@eecs.umich.edu return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 5608199SAli.Saidi@ARM.com q, u, size, machInst, vd, vn, vm); 5618591Sgblack@eecs.umich.edu } 5628591Sgblack@eecs.umich.edu } 5638591Sgblack@eecs.umich.edu case 0xa: 5648591Sgblack@eecs.umich.edu if (b) { 5658545Ssaidi@eecs.umich.edu return decodeNeonUSThreeReg<VpminD, VpminQ>( 5668545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5678199SAli.Saidi@ARM.com } else { 5688545Ssaidi@eecs.umich.edu return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>( 5698545Ssaidi@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5709046SAli.Saidi@ARM.com } 5718545Ssaidi@eecs.umich.edu case 0xb: 5728545Ssaidi@eecs.umich.edu if (b) { 5738545Ssaidi@eecs.umich.edu if (u) { 5748545Ssaidi@eecs.umich.edu 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) { 5818592Sgblack@eecs.umich.edu return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>( 5828592Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5838592Sgblack@eecs.umich.edu } else { 5848545Ssaidi@eecs.umich.edu return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>( 5858545Ssaidi@eecs.umich.edu q, size, machInst, vd, vn, vm); 5868545Ssaidi@eecs.umich.edu } 5878545Ssaidi@eecs.umich.edu } 5888591Sgblack@eecs.umich.edu case 0xc: 5898591Sgblack@eecs.umich.edu return new Unknown(machInst); 5908591Sgblack@eecs.umich.edu case 0xd: 5918545Ssaidi@eecs.umich.edu if (b) { 5928199SAli.Saidi@ARM.com if (u) { 5938199SAli.Saidi@ARM.com if (bits(c, 1) == 0) { 5948199SAli.Saidi@ARM.com if (q) { 5958199SAli.Saidi@ARM.com 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) { 6042292SN/A if (q) { 6052292SN/A return new NVmlaQFp<float>(machInst, vd, vn, vm); 6064032Sktlim@umich.edu } else { 6072292SN/A return new NVmlaDFp<float>(machInst, vd, vn, vm); 6082292SN/A } 6092292SN/A } else { 6107720Sgblack@eecs.umich.edu if (q) { 6117944SGiacomo.Gabrielli@arm.com return new NVmlsQFp<float>(machInst, vd, vn, vm); 6122292SN/A } else { 6134032Sktlim@umich.edu return new NVmlsDFp<float>(machInst, vd, vn, vm); 6144032Sktlim@umich.edu } 6152669Sktlim@umich.edu } 6162292SN/A } 6177944SGiacomo.Gabrielli@arm.com } else { 6187944SGiacomo.Gabrielli@arm.com if (u) { 6197944SGiacomo.Gabrielli@arm.com if (bits(c, 1) == 0) { 6207944SGiacomo.Gabrielli@arm.com if (q) { 6217597Sminkyu.jeong@arm.com return new VpaddQFp<float>(machInst, vd, vn, vm); 6227597Sminkyu.jeong@arm.com } else { 62310231Ssteve.reinhardt@amd.com return new VpaddDFp<float>(machInst, vd, vn, vm); 6242329SN/A } 6252329SN/A } else { 6262367SN/A if (q) { 6272367SN/A return new VabdQFp<float>(machInst, vd, vn, vm); 62810231Ssteve.reinhardt@amd.com } else { 6297848SAli.Saidi@ARM.com return new VabdDFp<float>(machInst, vd, vn, vm); 6307600Sminkyu.jeong@arm.com } 6317600Sminkyu.jeong@arm.com } 6327600Sminkyu.jeong@arm.com } else { 6334032Sktlim@umich.edu if (bits(c, 1) == 0) { 6343731Sktlim@umich.edu if (q) { 6352367SN/A return new VaddQFp<float>(machInst, vd, vn, vm); 6362367SN/A } else { 6372292SN/A return new VaddDFp<float>(machInst, vd, vn, vm); 6382292SN/A } 63910333Smitch.hayenga@arm.com } else { 6409046SAli.Saidi@ARM.com if (q) { 6414032Sktlim@umich.edu return new VsubQFp<float>(machInst, vd, vn, vm); 6424032Sktlim@umich.edu } else { 6434032Sktlim@umich.edu return new VsubDFp<float>(machInst, vd, vn, vm); 6448199SAli.Saidi@ARM.com } 6458199SAli.Saidi@ARM.com } 6462292SN/A } 6472292SN/A } 6482292SN/A case 0xe: 6492292SN/A 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 { 6617720Sgblack@eecs.umich.edu return new VacgtDFp<float>(machInst, vd, vn, vm); 6627720Sgblack@eecs.umich.edu } 6632292SN/A } 6644032Sktlim@umich.edu } else { 6654032Sktlim@umich.edu return new Unknown(machInst); 6662292SN/A } 6672292SN/A } else { 6682292SN/A if (u) { 6692292SN/A if (bits(c, 1) == 0) { 6702292SN/A if (q) { 6712292SN/A return new VcgeQFp<float>(machInst, vd, vn, vm); 6727944SGiacomo.Gabrielli@arm.com } else { 6737944SGiacomo.Gabrielli@arm.com return new VcgeDFp<float>(machInst, vd, vn, vm); 6747944SGiacomo.Gabrielli@arm.com } 6757944SGiacomo.Gabrielli@arm.com } else { 67610231Ssteve.reinhardt@amd.com if (q) { 6777848SAli.Saidi@ARM.com return new VcgtQFp<float>(machInst, vd, vn, vm); 6787848SAli.Saidi@ARM.com } else { 6792329SN/A return new VcgtDFp<float>(machInst, vd, vn, vm); 6807782Sminkyu.jeong@arm.com } 6817720Sgblack@eecs.umich.edu } 6822292SN/A } else { 6832292SN/A if (bits(c, 1) == 0) { 68410231Ssteve.reinhardt@amd.com if (q) { 6857782Sminkyu.jeong@arm.com return new VceqQFp<float>(machInst, vd, vn, vm); 6867782Sminkyu.jeong@arm.com } else { 6877782Sminkyu.jeong@arm.com return new VceqDFp<float>(machInst, vd, vn, vm); 6882292SN/A } 6892292SN/A } else { 6902292SN/A return new Unknown(machInst); 6912292SN/A } 6922336SN/A } 6932336SN/A } 6942336SN/A case 0xf: 6952329SN/A if (b) { 6962292SN/A if (u) { 6972329SN/A return new Unknown(machInst); 6982292SN/A } else { 6992292SN/A if (bits(c, 1) == 0) { 7008199SAli.Saidi@ARM.com if (q) { 7012292SN/A return new VrecpsQFp<float>(machInst, vd, vn, vm); 7022292SN/A } else { 7032292SN/A return new VrecpsDFp<float>(machInst, vd, vn, vm); 7042292SN/A } 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); 7107720Sgblack@eecs.umich.edu } 7117720Sgblack@eecs.umich.edu } 7122292SN/A } 7132292SN/A } else { 7142292SN/A if (u) { 7152292SN/A 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 } 7412329SN/A } 7422329SN/A } 7432292SN/A } 7442292SN/A } 7452292SN/A return new Unknown(machInst); 7462292SN/A } 7472292SN/A 7487720Sgblack@eecs.umich.edu static StaticInstPtr 7497720Sgblack@eecs.umich.edu decodeNeonOneRegModImm(ExtMachInst machInst) 7502292SN/A { 7512292SN/A const IntRegIndex vd = 7522292SN/A (IntRegIndex)(2 * (bits(machInst, 15, 12) | 7532292SN/A (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 7622292SN/A // Check for invalid immediate encodings and return an unknown op 7636974Stjones1@inf.ed.ac.uk // if it happens 7646974Stjones1@inf.ed.ac.uk bool immValid = true; 7656974Stjones1@inf.ed.ac.uk const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid); 7666974Stjones1@inf.ed.ac.uk if (!immValid) { 7676974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 7686974Stjones1@inf.ed.ac.uk } 7696974Stjones1@inf.ed.ac.uk 7706974Stjones1@inf.ed.ac.uk if (op) { 7716974Stjones1@inf.ed.ac.uk if (bits(cmode, 3) == 0) { 7726974Stjones1@inf.ed.ac.uk if (bits(cmode, 0) == 0) { 7736974Stjones1@inf.ed.ac.uk if (q) 7746974Stjones1@inf.ed.ac.uk return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 7756974Stjones1@inf.ed.ac.uk else 7766974Stjones1@inf.ed.ac.uk return new NVmvniD<uint64_t>(machInst, vd, bigImm); 7776974Stjones1@inf.ed.ac.uk } else { 7786974Stjones1@inf.ed.ac.uk if (q) 7792292SN/A return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 7802292SN/A else 7816974Stjones1@inf.ed.ac.uk return new NVbiciD<uint64_t>(machInst, vd, bigImm); 7826974Stjones1@inf.ed.ac.uk } 7836974Stjones1@inf.ed.ac.uk } else { 7846974Stjones1@inf.ed.ac.uk if (bits(cmode, 2) == 1) { 7856974Stjones1@inf.ed.ac.uk switch (bits(cmode, 1, 0)) { 7866974Stjones1@inf.ed.ac.uk case 0: 7872292SN/A case 1: 7882292SN/A if (q) 7892292SN/A return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 7902292SN/A else 7918727Snilay@cs.wisc.edu return new NVmvniD<uint64_t>(machInst, vd, bigImm); 7922292SN/A case 2: 7932292SN/A if (q) 79410333Smitch.hayenga@arm.com return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 7952678Sktlim@umich.edu else 7962678Sktlim@umich.edu return new NVmoviD<uint64_t>(machInst, vd, bigImm); 7972678Sktlim@umich.edu case 3: 7982678Sktlim@umich.edu if (q) 7992678Sktlim@umich.edu return new Unknown(machInst); 8002329SN/A else 8012329SN/A return new Unknown(machInst); 8022292SN/A } 8032292SN/A } else { 8042292SN/A if (bits(cmode, 0) == 0) { 8052292SN/A if (q) 8062292SN/A return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 8072292SN/A else 8082292SN/A return new NVmvniD<uint64_t>(machInst, vd, bigImm); 8092678Sktlim@umich.edu } else { 8102292SN/A if (q) 8112292SN/A return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 8122292SN/A else 8132292SN/A return new NVbiciD<uint64_t>(machInst, vd, bigImm); 8142292SN/A } 8152292SN/A } 8162292SN/A } 8172292SN/A } else { 8182292SN/A if (bits(cmode, 3) == 0) { 8192292SN/A if (bits(cmode, 0) == 0) { 8202292SN/A if (q) 8216974Stjones1@inf.ed.ac.uk return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8226974Stjones1@inf.ed.ac.uk else 8236974Stjones1@inf.ed.ac.uk return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8246974Stjones1@inf.ed.ac.uk } else { 8256974Stjones1@inf.ed.ac.uk if (q) 8262669Sktlim@umich.edu return new NVorriQ<uint64_t>(machInst, vd, bigImm); 8272669Sktlim@umich.edu else 8282669Sktlim@umich.edu return new NVorriD<uint64_t>(machInst, vd, bigImm); 8298481Sgblack@eecs.umich.edu } 8308481Sgblack@eecs.umich.edu } else { 8318481Sgblack@eecs.umich.edu if (bits(cmode, 2) == 1) { 8322292SN/A if (q) 8332292SN/A return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8342669Sktlim@umich.edu else 83510031SAli.Saidi@ARM.com return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8363772Sgblack@eecs.umich.edu } else { 83710031SAli.Saidi@ARM.com if (bits(cmode, 0) == 0) { 83810031SAli.Saidi@ARM.com if (q) 83910031SAli.Saidi@ARM.com return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 84010031SAli.Saidi@ARM.com else 8412669Sktlim@umich.edu return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8426974Stjones1@inf.ed.ac.uk } else { 8436974Stjones1@inf.ed.ac.uk if (q) 8442292SN/A return new NVorriQ<uint64_t>(machInst, vd, bigImm); 8452678Sktlim@umich.edu else 8462678Sktlim@umich.edu return new NVorriD<uint64_t>(machInst, vd, bigImm); 8472678Sktlim@umich.edu } 8482678Sktlim@umich.edu } 8496974Stjones1@inf.ed.ac.uk } 8506974Stjones1@inf.ed.ac.uk } 8516974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 8526974Stjones1@inf.ed.ac.uk } 85310342SCurtis.Dunham@arm.com 8546974Stjones1@inf.ed.ac.uk static StaticInstPtr 8556974Stjones1@inf.ed.ac.uk decodeNeonTwoRegAndShift(ExtMachInst machInst) 8566974Stjones1@inf.ed.ac.uk { 8576974Stjones1@inf.ed.ac.uk const uint32_t a = bits(machInst, 11, 8); 85810342SCurtis.Dunham@arm.com const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 85910342SCurtis.Dunham@arm.com const bool b = bits(machInst, 6); 8606974Stjones1@inf.ed.ac.uk const bool l = bits(machInst, 7); 8616974Stjones1@inf.ed.ac.uk const IntRegIndex vd = 8626974Stjones1@inf.ed.ac.uk (IntRegIndex)(2 * (bits(machInst, 15, 12) | 8636974Stjones1@inf.ed.ac.uk (bits(machInst, 22) << 4))); 8646974Stjones1@inf.ed.ac.uk const IntRegIndex vm = 8656974Stjones1@inf.ed.ac.uk (IntRegIndex)(2 * (bits(machInst, 3, 0) | 8666974Stjones1@inf.ed.ac.uk (bits(machInst, 5) << 4))); 8676974Stjones1@inf.ed.ac.uk unsigned imm6 = bits(machInst, 21, 16); 8686974Stjones1@inf.ed.ac.uk unsigned imm = ((l ? 1 : 0) << 6) | imm6; 8696974Stjones1@inf.ed.ac.uk unsigned size = 3; 8706974Stjones1@inf.ed.ac.uk unsigned lShiftAmt = 0; 8716974Stjones1@inf.ed.ac.uk unsigned bitSel; 8726974Stjones1@inf.ed.ac.uk for (bitSel = 1 << 6; true; bitSel >>= 1) { 8736974Stjones1@inf.ed.ac.uk if (bitSel & imm) 8742678Sktlim@umich.edu break; 8757720Sgblack@eecs.umich.edu else if (!size) 8762292SN/A return new Unknown(machInst); 8777720Sgblack@eecs.umich.edu size--; 8783797Sgblack@eecs.umich.edu } 8793221Sktlim@umich.edu lShiftAmt = imm6 & ~bitSel; 8802292SN/A unsigned rShiftAmt = 0; 8812693Sktlim@umich.edu if (a != 0xe && a != 0xf) { 8824350Sgblack@eecs.umich.edu if (size > 2) 8836974Stjones1@inf.ed.ac.uk rShiftAmt = 64 - imm6; 8843326Sktlim@umich.edu else 8853326Sktlim@umich.edu rShiftAmt = 2 * (8 << size) - imm6; 8863326Sktlim@umich.edu } 8879046SAli.Saidi@ARM.com 88810030SAli.Saidi@ARM.com switch (a) { 8899046SAli.Saidi@ARM.com case 0x0: 8903326Sktlim@umich.edu return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 8913326Sktlim@umich.edu b, u, size, machInst, vd, vm, rShiftAmt); 8923326Sktlim@umich.edu case 0x1: 8933326Sktlim@umich.edu return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 8943326Sktlim@umich.edu b, u, size, machInst, vd, vm, rShiftAmt); 8953326Sktlim@umich.edu case 0x2: 8963326Sktlim@umich.edu return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 8977823Ssteve.reinhardt@amd.com b, u, size, machInst, vd, vm, rShiftAmt); 8988887Sgeoffrey.blake@arm.com case 0x3: 8998887Sgeoffrey.blake@arm.com return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 9008887Sgeoffrey.blake@arm.com b, u, size, machInst, vd, vm, rShiftAmt); 9018887Sgeoffrey.blake@arm.com case 0x4: 9028887Sgeoffrey.blake@arm.com if (u) { 9038887Sgeoffrey.blake@arm.com return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 9043326Sktlim@umich.edu b, size, machInst, vd, vm, rShiftAmt); 9053326Sktlim@umich.edu } else { 9063326Sktlim@umich.edu return new Unknown(machInst); 9072693Sktlim@umich.edu } 9082693Sktlim@umich.edu case 0x5: 9092693Sktlim@umich.edu if (u) { 9102693Sktlim@umich.edu return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 9112693Sktlim@umich.edu b, size, machInst, vd, vm, lShiftAmt); 9122693Sktlim@umich.edu } else { 9138481Sgblack@eecs.umich.edu return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 9148481Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9158481Sgblack@eecs.umich.edu } 9168481Sgblack@eecs.umich.edu case 0x6: 9178481Sgblack@eecs.umich.edu case 0x7: 9188481Sgblack@eecs.umich.edu if (u) { 9198481Sgblack@eecs.umich.edu if (a == 0x6) { 9208481Sgblack@eecs.umich.edu return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 9218481Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9228481Sgblack@eecs.umich.edu } else { 9238481Sgblack@eecs.umich.edu return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 9248481Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9258481Sgblack@eecs.umich.edu } 9268481Sgblack@eecs.umich.edu } else { 9278481Sgblack@eecs.umich.edu return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 9288481Sgblack@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 9298481Sgblack@eecs.umich.edu } 9308481Sgblack@eecs.umich.edu case 0x8: 9318481Sgblack@eecs.umich.edu if (l) { 9328481Sgblack@eecs.umich.edu return new Unknown(machInst); 9338481Sgblack@eecs.umich.edu } else if (u) { 9344032Sktlim@umich.edu return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 9353221Sktlim@umich.edu b, size, machInst, vd, vm, rShiftAmt); 9363221Sktlim@umich.edu } else { 9376974Stjones1@inf.ed.ac.uk return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 9386974Stjones1@inf.ed.ac.uk b, size, machInst, vd, vm, rShiftAmt); 9398481Sgblack@eecs.umich.edu } 9406974Stjones1@inf.ed.ac.uk case 0x9: 9416974Stjones1@inf.ed.ac.uk if (l) { 9426974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 9432669Sktlim@umich.edu } else if (u) { 9446974Stjones1@inf.ed.ac.uk return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 9456974Stjones1@inf.ed.ac.uk b, size, machInst, vd, vm, rShiftAmt); 9468481Sgblack@eecs.umich.edu } else { 9476974Stjones1@inf.ed.ac.uk return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 9486974Stjones1@inf.ed.ac.uk b, size, machInst, vd, vm, rShiftAmt); 9496974Stjones1@inf.ed.ac.uk } 9506974Stjones1@inf.ed.ac.uk case 0xa: 9516974Stjones1@inf.ed.ac.uk if (l || b) { 9526974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 9536974Stjones1@inf.ed.ac.uk } else { 9546974Stjones1@inf.ed.ac.uk return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 9556974Stjones1@inf.ed.ac.uk lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); 9566974Stjones1@inf.ed.ac.uk } 9576974Stjones1@inf.ed.ac.uk case 0xe: 9586974Stjones1@inf.ed.ac.uk if (l) { 9596974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 9606974Stjones1@inf.ed.ac.uk } else { 9616974Stjones1@inf.ed.ac.uk if (bits(imm6, 5) == 0) 9626974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 9636974Stjones1@inf.ed.ac.uk if (u) { 9646974Stjones1@inf.ed.ac.uk if (b) { 9656974Stjones1@inf.ed.ac.uk return new NVcvtu2fpQ<float>( 9666974Stjones1@inf.ed.ac.uk machInst, vd, vm, 64 - imm6); 9676974Stjones1@inf.ed.ac.uk } else { 9686974Stjones1@inf.ed.ac.uk return new NVcvtu2fpD<float>( 9696974Stjones1@inf.ed.ac.uk machInst, vd, vm, 64 - imm6); 9706974Stjones1@inf.ed.ac.uk } 9712292SN/A } else { 9722292SN/A if (b) { 9732292SN/A return new NVcvts2fpQ<float>( 9742292SN/A machInst, vd, vm, 64 - imm6); 9752292SN/A } else { 9762292SN/A return new NVcvts2fpD<float>( 9772292SN/A machInst, vd, vm, 64 - imm6); 9782292SN/A } 9792292SN/A } 9802292SN/A } 9812292SN/A case 0xf: 9822292SN/A if (l) { 9832292SN/A return new Unknown(machInst); 9842292SN/A } else { 9852292SN/A if (bits(imm6, 5) == 0) 9862292SN/A return new Unknown(machInst); 9872292SN/A if (u) { 9882292SN/A if (b) { 9892292SN/A return new NVcvt2ufxQ<float>( 9902292SN/A machInst, vd, vm, 64 - imm6); 9912292SN/A } else { 9922292SN/A return new NVcvt2ufxD<float>( 9932292SN/A machInst, vd, vm, 64 - imm6); 9942292SN/A } 9952292SN/A } else { 9962292SN/A if (b) { 9972292SN/A return new NVcvt2sfxQ<float>( 9982292SN/A machInst, vd, vm, 64 - imm6); 9992329SN/A } else { 10002292SN/A return new NVcvt2sfxD<float>( 10012292SN/A machInst, vd, vm, 64 - imm6); 10022292SN/A } 10032292SN/A } 10042292SN/A } 10057720Sgblack@eecs.umich.edu } 10062292SN/A return new Unknown(machInst); 10077720Sgblack@eecs.umich.edu } 10082292SN/A 10092292SN/A static StaticInstPtr 10102292SN/A decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 10112292SN/A { 10122292SN/A const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 10132292SN/A const uint32_t a = bits(machInst, 11, 8); 10142292SN/A const IntRegIndex vd = 10152292SN/A (IntRegIndex)(2 * (bits(machInst, 15, 12) | 10162329SN/A (bits(machInst, 22) << 4))); 10172731Sktlim@umich.edu const IntRegIndex vn = 10182292SN/A (IntRegIndex)(2 * (bits(machInst, 19, 16) | 10192292SN/A (bits(machInst, 7) << 4))); 10202292SN/A const IntRegIndex vm = 10212292SN/A (IntRegIndex)(2 * (bits(machInst, 3, 0) | 10222292SN/A (bits(machInst, 5) << 4))); 10232292SN/A const unsigned size = bits(machInst, 21, 20); 10242292SN/A switch (a) { 10252727Sktlim@umich.edu case 0x0: 10262292SN/A return decodeNeonUSThreeUSReg<Vaddl>( 10272292SN/A u, size, machInst, vd, vn, vm); 10284032Sktlim@umich.edu case 0x1: 10294032Sktlim@umich.edu return decodeNeonUSThreeUSReg<Vaddw>( 10304032Sktlim@umich.edu u, size, machInst, vd, vn, vm); 10314032Sktlim@umich.edu case 0x2: 10322292SN/A return decodeNeonUSThreeUSReg<Vsubl>( 10332292SN/A u, size, machInst, vd, vn, vm); 10342292SN/A case 0x3: 10352292SN/A return decodeNeonUSThreeUSReg<Vsubw>( 10362292SN/A u, size, machInst, vd, vn, vm); 10372329SN/A case 0x4: 10382292SN/A if (u) { 10392292SN/A return decodeNeonUThreeUSReg<Vraddhn>( 10402292SN/A size, machInst, vd, vn, vm); 10412292SN/A } else { 10427720Sgblack@eecs.umich.edu return decodeNeonUThreeUSReg<Vaddhn>( 10432292SN/A size, machInst, vd, vn, vm); 10447720Sgblack@eecs.umich.edu } 10452292SN/A case 0x5: 10462292SN/A return decodeNeonUSThreeUSReg<Vabal>( 10472329SN/A u, size, machInst, vd, vn, vm); 10482329SN/A case 0x6: 10492292SN/A if (u) { 10502292SN/A return decodeNeonUThreeUSReg<Vrsubhn>( 10512292SN/A size, machInst, vd, vn, vm); 10522292SN/A } else { 10532292SN/A return decodeNeonUThreeUSReg<Vsubhn>( 10542292SN/A size, machInst, vd, vn, vm); 10552292SN/A } 10562329SN/A case 0x7: 10572731Sktlim@umich.edu if (bits(machInst, 23)) { 10582292SN/A return decodeNeonUSThreeUSReg<Vabdl>( 10592292SN/A u, size, machInst, vd, vn, vm); 10602292SN/A } else { 10614032Sktlim@umich.edu return decodeNeonUSThreeReg<VabdD, VabdQ>( 10624032Sktlim@umich.edu bits(machInst, 6), u, size, machInst, vd, vn, vm); 10634032Sktlim@umich.edu } 10644032Sktlim@umich.edu case 0x8: 10656974Stjones1@inf.ed.ac.uk return decodeNeonUSThreeUSReg<Vmlal>( 10666974Stjones1@inf.ed.ac.uk u, size, machInst, vd, vn, vm); 10676974Stjones1@inf.ed.ac.uk case 0xa: 10686974Stjones1@inf.ed.ac.uk return decodeNeonUSThreeUSReg<Vmlsl>( 10696974Stjones1@inf.ed.ac.uk u, size, machInst, vd, vn, vm); 10706974Stjones1@inf.ed.ac.uk case 0x9: 10716974Stjones1@inf.ed.ac.uk if (u) { 10724032Sktlim@umich.edu return new Unknown(machInst); 10732292SN/A } else { 10742292SN/A return decodeNeonSThreeUSReg<Vqdmlal>( 10752292SN/A size, machInst, vd, vn, vm); 10762292SN/A } 10772292SN/A case 0xb: 10782292SN/A if (u) { 10792292SN/A return new Unknown(machInst); 10802727Sktlim@umich.edu } else { 10812292SN/A return decodeNeonSThreeUSReg<Vqdmlsl>( 10822292SN/A size, machInst, vd, vn, vm); 10832292SN/A } 10842292SN/A case 0xc: 10852292SN/A return decodeNeonUSThreeUSReg<Vmull>( 10863349Sbinkertn@umich.edu u, size, machInst, vd, vn, vm); 10872693Sktlim@umich.edu case 0xd: 10882693Sktlim@umich.edu if (u) { 10892693Sktlim@umich.edu return new Unknown(machInst); 10902693Sktlim@umich.edu } else { 10912693Sktlim@umich.edu return decodeNeonSThreeUSReg<Vqdmull>( 10922693Sktlim@umich.edu size, machInst, vd, vn, vm); 10932693Sktlim@umich.edu } 10942693Sktlim@umich.edu case 0xe: 10952693Sktlim@umich.edu return decodeNeonUThreeUSReg<Vmullp>( 10962693Sktlim@umich.edu size, machInst, vd, vn, vm); 10972693Sktlim@umich.edu } 10982693Sktlim@umich.edu return new Unknown(machInst); 10992693Sktlim@umich.edu } 11002693Sktlim@umich.edu 11012693Sktlim@umich.edu static StaticInstPtr 11022693Sktlim@umich.edu decodeNeonTwoRegScalar(ExtMachInst machInst) 11038887Sgeoffrey.blake@arm.com { 11042693Sktlim@umich.edu const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 11052732Sktlim@umich.edu const uint32_t a = bits(machInst, 11, 8); 11062693Sktlim@umich.edu const unsigned size = bits(machInst, 21, 20); 11072693Sktlim@umich.edu const IntRegIndex vd = 11082693Sktlim@umich.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 11098727Snilay@cs.wisc.edu (bits(machInst, 22) << 4))); 11108727Snilay@cs.wisc.edu const IntRegIndex vn = 11118727Snilay@cs.wisc.edu (IntRegIndex)(2 * (bits(machInst, 19, 16) | 11128727Snilay@cs.wisc.edu (bits(machInst, 7) << 4))); 11132693Sktlim@umich.edu const IntRegIndex vm = (size == 2) ? 11142693Sktlim@umich.edu (IntRegIndex)(2 * bits(machInst, 3, 0)) : 11152693Sktlim@umich.edu (IntRegIndex)(2 * bits(machInst, 2, 0)); 11162693Sktlim@umich.edu const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 11172693Sktlim@umich.edu (bits(machInst, 3) | (bits(machInst, 5) << 1)); 11182678Sktlim@umich.edu switch (a) { 11192678Sktlim@umich.edu case 0x0: 11202678Sktlim@umich.edu if (u) { 11212678Sktlim@umich.edu switch (size) { 11222678Sktlim@umich.edu case 1: 11232678Sktlim@umich.edu return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 11242678Sktlim@umich.edu case 2: 11252727Sktlim@umich.edu return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index); 11262678Sktlim@umich.edu default: 11272678Sktlim@umich.edu return new Unknown(machInst); 11282678Sktlim@umich.edu } 11292678Sktlim@umich.edu } else { 11302678Sktlim@umich.edu switch (size) { 11312678Sktlim@umich.edu case 1: 11322678Sktlim@umich.edu return new VmlasD<uint16_t>(machInst, vd, vn, vm, index); 11332678Sktlim@umich.edu case 2: 11342678Sktlim@umich.edu return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 11352678Sktlim@umich.edu default: 11362678Sktlim@umich.edu return new Unknown(machInst); 11372678Sktlim@umich.edu } 11382678Sktlim@umich.edu } 11392678Sktlim@umich.edu case 0x1: 11407598Sminkyu.jeong@arm.com if (u) 11417598Sminkyu.jeong@arm.com return new VmlasQFp<float>(machInst, vd, vn, vm, index); 11427598Sminkyu.jeong@arm.com else 11432678Sktlim@umich.edu return new VmlasDFp<float>(machInst, vd, vn, vm, index); 11442678Sktlim@umich.edu case 0x4: 11452678Sktlim@umich.edu if (u) { 11462678Sktlim@umich.edu switch (size) { 11472292SN/A case 1: 11482292SN/A return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 11492292SN/A case 2: 11502292SN/A return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index); 11512292SN/A default: 11522292SN/A return new Unknown(machInst); 11532292SN/A } 11542292SN/A } else { 11553126Sktlim@umich.edu switch (size) { 11562292SN/A case 1: 11572292SN/A return new VmlssD<uint16_t>(machInst, vd, vn, vm, index); 11582292SN/A case 2: 11592292SN/A return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 11602292SN/A default: 11612292SN/A return new Unknown(machInst); 11622292SN/A } 11632292SN/A } 11642292SN/A case 0x5: 11652292SN/A if (u) 11662292SN/A return new VmlssQFp<float>(machInst, vd, vn, vm, index); 11672292SN/A else 11682292SN/A return new VmlssDFp<float>(machInst, vd, vn, vm, index); 11692329SN/A case 0x2: 11702329SN/A if (u) { 11712329SN/A switch (size) { 11722292SN/A case 1: 11739527SMatt.Horsnell@arm.com return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 11749527SMatt.Horsnell@arm.com case 2: 11759527SMatt.Horsnell@arm.com return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 11769527SMatt.Horsnell@arm.com default: 11779527SMatt.Horsnell@arm.com return new Unknown(machInst); 11789527SMatt.Horsnell@arm.com } 11799527SMatt.Horsnell@arm.com } else { 11802292SN/A switch (size) { 11812292SN/A case 1: 11822292SN/A return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 11832292SN/A case 2: 11842292SN/A return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 11852292SN/A default: 11862292SN/A return new Unknown(machInst); 11872292SN/A } 11882292SN/A } 11892316SN/A case 0x6: 11902316SN/A if (u) { 11912329SN/A switch (size) { 11928727Snilay@cs.wisc.edu case 1: 11938727Snilay@cs.wisc.edu return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 11948727Snilay@cs.wisc.edu case 2: 11958727Snilay@cs.wisc.edu return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 11962329SN/A default: 11972329SN/A return new Unknown(machInst); 11982329SN/A } 11992316SN/A } else { 12002732Sktlim@umich.edu switch (size) { 12012316SN/A case 1: 12022292SN/A return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 12032292SN/A case 2: 12042292SN/A return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 12056974Stjones1@inf.ed.ac.uk default: 12066974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 12076974Stjones1@inf.ed.ac.uk } 12088975Sandreas.hansson@arm.com } 12096974Stjones1@inf.ed.ac.uk case 0x3: 12106974Stjones1@inf.ed.ac.uk if (u) { 12116974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 12126974Stjones1@inf.ed.ac.uk } else { 12136974Stjones1@inf.ed.ac.uk switch (size) { 12146974Stjones1@inf.ed.ac.uk case 1: 12156974Stjones1@inf.ed.ac.uk return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 12166974Stjones1@inf.ed.ac.uk case 2: 12176974Stjones1@inf.ed.ac.uk return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 12186974Stjones1@inf.ed.ac.uk default: 12196974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 12202693Sktlim@umich.edu } 12212693Sktlim@umich.edu } 12222693Sktlim@umich.edu case 0x7: 12232698Sktlim@umich.edu if (u) { 12244985Sktlim@umich.edu return new Unknown(machInst); 12252698Sktlim@umich.edu } else { 12262693Sktlim@umich.edu switch (size) { 12278587Snilay@cs.wisc.edu case 1: 12288587Snilay@cs.wisc.edu return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 12298587Snilay@cs.wisc.edu case 2: 12308975Sandreas.hansson@arm.com return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 12316974Stjones1@inf.ed.ac.uk default: 12328133SAli.Saidi@ARM.com return new Unknown(machInst); 12338133SAli.Saidi@ARM.com } 12348133SAli.Saidi@ARM.com } 12356974Stjones1@inf.ed.ac.uk case 0x8: 12366974Stjones1@inf.ed.ac.uk if (u) { 12372699Sktlim@umich.edu switch (size) { 12382693Sktlim@umich.edu case 1: 12396974Stjones1@inf.ed.ac.uk return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 12406974Stjones1@inf.ed.ac.uk case 2: 12416974Stjones1@inf.ed.ac.uk return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index); 12426974Stjones1@inf.ed.ac.uk default: 12436974Stjones1@inf.ed.ac.uk return new Unknown(machInst); 12446974Stjones1@inf.ed.ac.uk } 12456974Stjones1@inf.ed.ac.uk } else { 12466974Stjones1@inf.ed.ac.uk switch (size) { 12472693Sktlim@umich.edu case 1: 12482693Sktlim@umich.edu return new VmulsD<uint16_t>(machInst, vd, vn, vm, index); 12492727Sktlim@umich.edu case 2: 12502693Sktlim@umich.edu return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 12512693Sktlim@umich.edu default: 12522693Sktlim@umich.edu return new Unknown(machInst); 12532693Sktlim@umich.edu } 12542693Sktlim@umich.edu } 12552292SN/A case 0x9: 12569440SAndreas.Sandberg@ARM.com if (u) 12572292SN/A return new VmulsQFp<float>(machInst, vd, vn, vm, index); 12582292SN/A else 12592292SN/A return new VmulsDFp<float>(machInst, vd, vn, vm, index); 12602292SN/A case 0xa: 12612292SN/A if (u) { 12622292SN/A switch (size) { 12632292SN/A case 1: 12649440SAndreas.Sandberg@ARM.com return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 12652292SN/A case 2: 12662292SN/A return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 12672292SN/A default: 12682292SN/A return new Unknown(machInst); 12692292SN/A } 12702292SN/A } else { 12712292SN/A switch (size) { 12729440SAndreas.Sandberg@ARM.com case 1: 12732292SN/A return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 12742292SN/A case 2: 12752292SN/A return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 12762292SN/A default: 12772292SN/A return new Unknown(machInst); 12782292SN/A } 12792292SN/A } 12809440SAndreas.Sandberg@ARM.com case 0xb: 12812292SN/A if (u) { 12822292SN/A return new Unknown(machInst); 12832292SN/A } else { 12842292SN/A if (u) { 12852329SN/A switch (size) { 12862329SN/A case 1: 12872329SN/A return new Vqdmulls<uint16_t>( 12889440SAndreas.Sandberg@ARM.com machInst, vd, vn, vm, index); 12892329SN/A case 2: 12902329SN/A return new Vqdmulls<uint32_t>( 12912329SN/A machInst, vd, vn, vm, index); 12922329SN/A default: 12932329SN/A return new Unknown(machInst); 12942329SN/A } 12952329SN/A } else { 12962329SN/A switch (size) { 12979440SAndreas.Sandberg@ARM.com case 1: 12989440SAndreas.Sandberg@ARM.com return new Vqdmulls<int16_t>( 12992329SN/A machInst, vd, vn, vm, index); 13002329SN/A case 2: 13012329SN/A return new Vqdmulls<int32_t>( 13029440SAndreas.Sandberg@ARM.com machInst, vd, vn, vm, index); 13032329SN/A default: 13042329SN/A return new Unknown(machInst); 13052329SN/A } 13062329SN/A } 13072329SN/A } 13082329SN/A case 0xc: 13092329SN/A if (u) { 13109440SAndreas.Sandberg@ARM.com switch (size) { 13119440SAndreas.Sandberg@ARM.com case 1: 13122329SN/A return new VqdmulhsQ<int16_t>( 13132329SN/A machInst, vd, vn, vm, index); 13142329SN/A case 2: 13152329SN/A return new VqdmulhsQ<int32_t>( 13162329SN/A machInst, vd, vn, vm, index); 13172329SN/A default: 13189944Smatt.horsnell@ARM.com return new Unknown(machInst); 13199944Smatt.horsnell@ARM.com } 1320 } else { 1321 switch (size) { 1322 case 1: 1323 return new VqdmulhsD<int16_t>( 1324 machInst, vd, vn, vm, index); 1325 case 2: 1326 return new VqdmulhsD<int32_t>( 1327 machInst, vd, vn, vm, index); 1328 default: 1329 return new Unknown(machInst); 1330 } 1331 } 1332 case 0xd: 1333 if (u) { 1334 switch (size) { 1335 case 1: 1336 return new VqrdmulhsQ<int16_t>( 1337 machInst, vd, vn, vm, index); 1338 case 2: 1339 return new VqrdmulhsQ<int32_t>( 1340 machInst, vd, vn, vm, index); 1341 default: 1342 return new Unknown(machInst); 1343 } 1344 } else { 1345 switch (size) { 1346 case 1: 1347 return new VqrdmulhsD<int16_t>( 1348 machInst, vd, vn, vm, index); 1349 case 2: 1350 return new VqrdmulhsD<int32_t>( 1351 machInst, vd, vn, vm, index); 1352 default: 1353 return new Unknown(machInst); 1354 } 1355 } 1356 } 1357 return new Unknown(machInst); 1358 } 1359 1360 static StaticInstPtr 1361 decodeNeonTwoRegMisc(ExtMachInst machInst) 1362 { 1363 const uint32_t a = bits(machInst, 17, 16); 1364 const uint32_t b = bits(machInst, 10, 6); 1365 const bool q = bits(machInst, 6); 1366 const IntRegIndex vd = 1367 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1368 (bits(machInst, 22) << 4))); 1369 const IntRegIndex vm = 1370 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1371 (bits(machInst, 5) << 4))); 1372 const unsigned size = bits(machInst, 19, 18); 1373 switch (a) { 1374 case 0x0: 1375 switch (bits(b, 4, 1)) { 1376 case 0x0: 1377 switch (size) { 1378 case 0: 1379 if (q) { 1380 return new NVrev64Q<uint8_t>(machInst, vd, vm); 1381 } else { 1382 return new NVrev64D<uint8_t>(machInst, vd, vm); 1383 } 1384 case 1: 1385 if (q) { 1386 return new NVrev64Q<uint16_t>(machInst, vd, vm); 1387 } else { 1388 return new NVrev64D<uint16_t>(machInst, vd, vm); 1389 } 1390 case 2: 1391 if (q) { 1392 return new NVrev64Q<uint32_t>(machInst, vd, vm); 1393 } else { 1394 return new NVrev64D<uint32_t>(machInst, vd, vm); 1395 } 1396 default: 1397 return new Unknown(machInst); 1398 } 1399 case 0x1: 1400 switch (size) { 1401 case 0: 1402 if (q) { 1403 return new NVrev32Q<uint8_t>(machInst, vd, vm); 1404 } else { 1405 return new NVrev32D<uint8_t>(machInst, vd, vm); 1406 } 1407 case 1: 1408 if (q) { 1409 return new NVrev32Q<uint16_t>(machInst, vd, vm); 1410 } else { 1411 return new NVrev32D<uint16_t>(machInst, vd, vm); 1412 } 1413 default: 1414 return new Unknown(machInst); 1415 } 1416 case 0x2: 1417 if (size != 0) { 1418 return new Unknown(machInst); 1419 } else if (q) { 1420 return new NVrev16Q<uint8_t>(machInst, vd, vm); 1421 } else { 1422 return new NVrev16D<uint8_t>(machInst, vd, vm); 1423 } 1424 case 0x4: 1425 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1426 q, size, machInst, vd, vm); 1427 case 0x5: 1428 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1429 q, size, machInst, vd, vm); 1430 case 0x8: 1431 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 1432 q, size, machInst, vd, vm); 1433 case 0x9: 1434 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 1435 q, size, machInst, vd, vm); 1436 case 0xa: 1437 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 1438 q, size, machInst, vd, vm); 1439 case 0xb: 1440 if (q) 1441 return new NVmvnQ<uint64_t>(machInst, vd, vm); 1442 else 1443 return new NVmvnD<uint64_t>(machInst, vd, vm); 1444 case 0xc: 1445 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 1446 q, size, machInst, vd, vm); 1447 case 0xd: 1448 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 1449 q, size, machInst, vd, vm); 1450 case 0xe: 1451 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 1452 q, size, machInst, vd, vm); 1453 case 0xf: 1454 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 1455 q, size, machInst, vd, vm); 1456 default: 1457 return new Unknown(machInst); 1458 } 1459 case 0x1: 1460 switch (bits(b, 3, 1)) { 1461 case 0x0: 1462 if (bits(b, 4)) { 1463 if (q) { 1464 return new NVcgtQFp<float>(machInst, vd, vm); 1465 } else { 1466 return new NVcgtDFp<float>(machInst, vd, vm); 1467 } 1468 } else { 1469 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 1470 q, size, machInst, vd, vm); 1471 } 1472 case 0x1: 1473 if (bits(b, 4)) { 1474 if (q) { 1475 return new NVcgeQFp<float>(machInst, vd, vm); 1476 } else { 1477 return new NVcgeDFp<float>(machInst, vd, vm); 1478 } 1479 } else { 1480 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 1481 q, size, machInst, vd, vm); 1482 } 1483 case 0x2: 1484 if (bits(b, 4)) { 1485 if (q) { 1486 return new NVceqQFp<float>(machInst, vd, vm); 1487 } else { 1488 return new NVceqDFp<float>(machInst, vd, vm); 1489 } 1490 } else { 1491 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 1492 q, size, machInst, vd, vm); 1493 } 1494 case 0x3: 1495 if (bits(b, 4)) { 1496 if (q) { 1497 return new NVcleQFp<float>(machInst, vd, vm); 1498 } else { 1499 return new NVcleDFp<float>(machInst, vd, vm); 1500 } 1501 } else { 1502 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 1503 q, size, machInst, vd, vm); 1504 } 1505 case 0x4: 1506 if (bits(b, 4)) { 1507 if (q) { 1508 return new NVcltQFp<float>(machInst, vd, vm); 1509 } else { 1510 return new NVcltDFp<float>(machInst, vd, vm); 1511 } 1512 } else { 1513 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 1514 q, size, machInst, vd, vm); 1515 } 1516 case 0x6: 1517 if (bits(machInst, 10)) { 1518 if (q) 1519 return new NVabsQFp<float>(machInst, vd, vm); 1520 else 1521 return new NVabsDFp<float>(machInst, vd, vm); 1522 } else { 1523 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 1524 q, size, machInst, vd, vm); 1525 } 1526 case 0x7: 1527 if (bits(machInst, 10)) { 1528 if (q) 1529 return new NVnegQFp<float>(machInst, vd, vm); 1530 else 1531 return new NVnegDFp<float>(machInst, vd, vm); 1532 } else { 1533 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 1534 q, size, machInst, vd, vm); 1535 } 1536 } 1537 case 0x2: 1538 switch (bits(b, 4, 1)) { 1539 case 0x0: 1540 if (q) 1541 return new NVswpQ<uint64_t>(machInst, vd, vm); 1542 else 1543 return new NVswpD<uint64_t>(machInst, vd, vm); 1544 case 0x1: 1545 return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>( 1546 q, size, machInst, vd, vm); 1547 case 0x2: 1548 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 1549 q, size, machInst, vd, vm); 1550 case 0x3: 1551 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 1552 q, size, machInst, vd, vm); 1553 case 0x4: 1554 if (b == 0x8) { 1555 return decodeNeonUTwoMiscUSReg<NVmovn>( 1556 size, machInst, vd, vm); 1557 } else { 1558 return decodeNeonSTwoMiscUSReg<NVqmovuns>( 1559 size, machInst, vd, vm); 1560 } 1561 case 0x5: 1562 if (q) { 1563 return decodeNeonUTwoMiscUSReg<NVqmovun>( 1564 size, machInst, vd, vm); 1565 } else { 1566 return decodeNeonSTwoMiscUSReg<NVqmovn>( 1567 size, machInst, vd, vm); 1568 } 1569 case 0x6: 1570 if (b == 0xc) { 1571 const IntRegIndex vd = 1572 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1573 (bits(machInst, 22) << 4))); 1574 const IntRegIndex vm = 1575 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1576 (bits(machInst, 5) << 4))); 1577 unsigned size = bits(machInst, 19, 18); 1578 return decodeNeonSTwoShiftUSReg<NVshll>( 1579 size, machInst, vd, vm, 8 << size); 1580 } else { 1581 return new Unknown(machInst); 1582 } 1583 case 0xc: 1584 case 0xe: 1585 if (b == 0x18) { 1586 if (size != 1 || (vm % 2)) 1587 return new Unknown(machInst); 1588 return new NVcvts2h<uint16_t>(machInst, vd, vm); 1589 } else if (b == 0x1c) { 1590 if (size != 1 || (vd % 2)) 1591 return new Unknown(machInst); 1592 return new NVcvth2s<uint16_t>(machInst, vd, vm); 1593 } else { 1594 return new Unknown(machInst); 1595 } 1596 default: 1597 return new Unknown(machInst); 1598 } 1599 case 0x3: 1600 if (bits(b, 4, 3) == 0x3) { 1601 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1602 return new Unknown(machInst); 1603 } else { 1604 if (bits(b, 2)) { 1605 if (bits(b, 1)) { 1606 if (q) { 1607 return new NVcvt2ufxQ<float>( 1608 machInst, vd, vm, 0); 1609 } else { 1610 return new NVcvt2ufxD<float>( 1611 machInst, vd, vm, 0); 1612 } 1613 } else { 1614 if (q) { 1615 return new NVcvt2sfxQ<float>( 1616 machInst, vd, vm, 0); 1617 } else { 1618 return new NVcvt2sfxD<float>( 1619 machInst, vd, vm, 0); 1620 } 1621 } 1622 } else { 1623 if (bits(b, 1)) { 1624 if (q) { 1625 return new NVcvtu2fpQ<float>( 1626 machInst, vd, vm, 0); 1627 } else { 1628 return new NVcvtu2fpD<float>( 1629 machInst, vd, vm, 0); 1630 } 1631 } else { 1632 if (q) { 1633 return new NVcvts2fpQ<float>( 1634 machInst, vd, vm, 0); 1635 } else { 1636 return new NVcvts2fpD<float>( 1637 machInst, vd, vm, 0); 1638 } 1639 } 1640 } 1641 } 1642 } else if ((b & 0x1a) == 0x10) { 1643 if (bits(b, 2)) { 1644 if (q) { 1645 return new NVrecpeQFp<float>(machInst, vd, vm); 1646 } else { 1647 return new NVrecpeDFp<float>(machInst, vd, vm); 1648 } 1649 } else { 1650 if (q) { 1651 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1652 } else { 1653 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1654 } 1655 } 1656 } else if ((b & 0x1a) == 0x12) { 1657 if (bits(b, 2)) { 1658 if (q) { 1659 return new NVrsqrteQFp<float>(machInst, vd, vm); 1660 } else { 1661 return new NVrsqrteDFp<float>(machInst, vd, vm); 1662 } 1663 } else { 1664 if (q) { 1665 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1666 } else { 1667 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1668 } 1669 } 1670 } else { 1671 return new Unknown(machInst); 1672 } 1673 } 1674 return new Unknown(machInst); 1675 } 1676 1677 StaticInstPtr 1678 decodeNeonData(ExtMachInst machInst) 1679 { 1680 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1681 const uint32_t a = bits(machInst, 23, 19); 1682 const uint32_t b = bits(machInst, 11, 8); 1683 const uint32_t c = bits(machInst, 7, 4); 1684 if (bits(a, 4) == 0) { 1685 return decodeNeonThreeRegistersSameLength(machInst); 1686 } else if ((c & 0x9) == 1) { 1687 if ((a & 0x7) == 0) { 1688 return decodeNeonOneRegModImm(machInst); 1689 } else { 1690 return decodeNeonTwoRegAndShift(machInst); 1691 } 1692 } else if ((c & 0x9) == 9) { 1693 return decodeNeonTwoRegAndShift(machInst); 1694 } else if (bits(a, 2, 1) != 0x3) { 1695 if ((c & 0x5) == 0) { 1696 return decodeNeonThreeRegDiffLengths(machInst); 1697 } else if ((c & 0x5) == 4) { 1698 return decodeNeonTwoRegScalar(machInst); 1699 } 1700 } else if ((a & 0x16) == 0x16) { 1701 const IntRegIndex vd = 1702 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1703 (bits(machInst, 22) << 4))); 1704 const IntRegIndex vn = 1705 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1706 (bits(machInst, 7) << 4))); 1707 const IntRegIndex vm = 1708 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1709 (bits(machInst, 5) << 4))); 1710 if (!u) { 1711 if (bits(c, 0) == 0) { 1712 unsigned imm4 = bits(machInst, 11, 8); 1713 bool q = bits(machInst, 6); 1714 if (imm4 >= 16 && !q) 1715 return new Unknown(machInst); 1716 if (q) { 1717 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1718 } else { 1719 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1720 } 1721 } 1722 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1723 return decodeNeonTwoRegMisc(machInst); 1724 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { 1725 unsigned length = bits(machInst, 9, 8) + 1; 1726 if ((uint32_t)vn / 2 + length > 32) 1727 return new Unknown(machInst); 1728 if (bits(machInst, 6) == 0) { 1729 switch (length) { 1730 case 1: 1731 return new NVtbl1(machInst, vd, vn, vm); 1732 case 2: 1733 return new NVtbl2(machInst, vd, vn, vm); 1734 case 3: 1735 return new NVtbl3(machInst, vd, vn, vm); 1736 case 4: 1737 return new NVtbl4(machInst, vd, vn, vm); 1738 } 1739 } else { 1740 switch (length) { 1741 case 1: 1742 return new NVtbx1(machInst, vd, vn, vm); 1743 case 2: 1744 return new NVtbx2(machInst, vd, vn, vm); 1745 case 3: 1746 return new NVtbx3(machInst, vd, vn, vm); 1747 case 4: 1748 return new NVtbx4(machInst, vd, vn, vm); 1749 } 1750 } 1751 } else if (b == 0xc && (c & 0x9) == 0) { 1752 unsigned imm4 = bits(machInst, 19, 16); 1753 if (bits(imm4, 2, 0) == 0) 1754 return new Unknown(machInst); 1755 unsigned size = 0; 1756 while ((imm4 & 0x1) == 0) { 1757 size++; 1758 imm4 >>= 1; 1759 } 1760 unsigned index = imm4 >> 1; 1761 const bool q = bits(machInst, 6); 1762 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1763 q, size, machInst, vd, vm, index); 1764 } 1765 } 1766 return new Unknown(machInst); 1767 } 1768 ''' 1769}}; 1770 1771def format ThumbNeonMem() {{ 1772 decode_block = ''' 1773 return decodeNeonMem(machInst); 1774 ''' 1775}}; 1776 1777def format ThumbNeonData() {{ 1778 decode_block = ''' 1779 return decodeNeonData(machInst); 1780 ''' 1781}}; 1782 1783let {{ 1784 header_output = ''' 1785 StaticInstPtr 1786 decodeExtensionRegLoadStore(ExtMachInst machInst); 1787 ''' 1788 decoder_output = ''' 1789 StaticInstPtr 1790 decodeExtensionRegLoadStore(ExtMachInst machInst) 1791 { 1792 const uint32_t opcode = bits(machInst, 24, 20); 1793 const uint32_t offset = bits(machInst, 7, 0); 1794 const bool single = (bits(machInst, 8) == 0); 1795 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1796 RegIndex vd; 1797 if (single) { 1798 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1799 bits(machInst, 22)); 1800 } else { 1801 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1802 (bits(machInst, 22) << 5)); 1803 } 1804 switch (bits(opcode, 4, 3)) { 1805 case 0x0: 1806 if (bits(opcode, 4, 1) == 0x2 && 1807 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1808 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1809 if ((bits(machInst, 7, 4) & 0xd) != 1) { 1810 break; 1811 } 1812 const IntRegIndex rt = 1813 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1814 const IntRegIndex rt2 = 1815 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1816 const bool op = bits(machInst, 20); 1817 uint32_t vm; 1818 if (single) { 1819 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1820 } else { 1821 vm = (bits(machInst, 3, 0) << 1) | 1822 (bits(machInst, 5) << 5); 1823 } 1824 if (op) { 1825 return new Vmov2Core2Reg(machInst, rt, rt2, 1826 (IntRegIndex)vm); 1827 } else { 1828 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1829 rt, rt2); 1830 } 1831 } 1832 break; 1833 case 0x1: 1834 { 1835 if (offset == 0 || vd + offset/2 > NumFloatArchRegs) { 1836 break; 1837 } 1838 switch (bits(opcode, 1, 0)) { 1839 case 0x0: 1840 return new VLdmStm(machInst, rn, vd, single, 1841 true, false, false, offset); 1842 case 0x1: 1843 return new VLdmStm(machInst, rn, vd, single, 1844 true, false, true, offset); 1845 case 0x2: 1846 return new VLdmStm(machInst, rn, vd, single, 1847 true, true, false, offset); 1848 case 0x3: 1849 // If rn == sp, then this is called vpop. 1850 return new VLdmStm(machInst, rn, vd, single, 1851 true, true, true, offset); 1852 } 1853 } 1854 case 0x2: 1855 if (bits(opcode, 1, 0) == 0x2) { 1856 // If rn == sp, then this is called vpush. 1857 return new VLdmStm(machInst, rn, vd, single, 1858 false, true, false, offset); 1859 } else if (bits(opcode, 1, 0) == 0x3) { 1860 return new VLdmStm(machInst, rn, vd, single, 1861 false, true, true, offset); 1862 } 1863 // Fall through on purpose 1864 case 0x3: 1865 const bool up = (bits(machInst, 23) == 1); 1866 const uint32_t imm = bits(machInst, 7, 0) << 2; 1867 RegIndex vd; 1868 if (single) { 1869 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1870 (bits(machInst, 22))); 1871 } else { 1872 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1873 (bits(machInst, 22) << 5)); 1874 } 1875 if (bits(opcode, 1, 0) == 0x0) { 1876 if (single) { 1877 if (up) { 1878 return new %(vstr_us)s(machInst, vd, rn, up, imm); 1879 } else { 1880 return new %(vstr_s)s(machInst, vd, rn, up, imm); 1881 } 1882 } else { 1883 if (up) { 1884 return new %(vstr_ud)s(machInst, vd, vd + 1, 1885 rn, up, imm); 1886 } else { 1887 return new %(vstr_d)s(machInst, vd, vd + 1, 1888 rn, up, imm); 1889 } 1890 } 1891 } else if (bits(opcode, 1, 0) == 0x1) { 1892 if (single) { 1893 if (up) { 1894 return new %(vldr_us)s(machInst, vd, rn, up, imm); 1895 } else { 1896 return new %(vldr_s)s(machInst, vd, rn, up, imm); 1897 } 1898 } else { 1899 if (up) { 1900 return new %(vldr_ud)s(machInst, vd, vd + 1, 1901 rn, up, imm); 1902 } else { 1903 return new %(vldr_d)s(machInst, vd, vd + 1, 1904 rn, up, imm); 1905 } 1906 } 1907 } 1908 } 1909 return new Unknown(machInst); 1910 } 1911 ''' % { 1912 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 1913 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 1914 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 1915 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 1916 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 1917 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 1918 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 1919 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 1920 } 1921}}; 1922 1923def format ExtensionRegLoadStore() {{ 1924 decode_block = ''' 1925 return decodeExtensionRegLoadStore(machInst); 1926 ''' 1927}}; 1928 1929let {{ 1930 header_output = ''' 1931 StaticInstPtr 1932 decodeShortFpTransfer(ExtMachInst machInst); 1933 ''' 1934 decoder_output = ''' 1935 StaticInstPtr 1936 decodeShortFpTransfer(ExtMachInst machInst) 1937 { 1938 const uint32_t l = bits(machInst, 20); 1939 const uint32_t c = bits(machInst, 8); 1940 const uint32_t a = bits(machInst, 23, 21); 1941 const uint32_t b = bits(machInst, 6, 5); 1942 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 1943 (machInst.thumb == 0 && machInst.condCode == 0xf)) { 1944 return new Unknown(machInst); 1945 } 1946 if (l == 0 && c == 0) { 1947 if (a == 0) { 1948 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 1949 bits(machInst, 7); 1950 const IntRegIndex rt = 1951 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1952 if (bits(machInst, 20) == 1) { 1953 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 1954 } else { 1955 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 1956 } 1957 } else if (a == 0x7) { 1958 const IntRegIndex rt = 1959 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1960 uint32_t specReg = bits(machInst, 19, 16); 1961 switch (specReg) { 1962 case 0: 1963 specReg = MISCREG_FPSID; 1964 break; 1965 case 1: 1966 specReg = MISCREG_FPSCR; 1967 break; 1968 case 6: 1969 specReg = MISCREG_MVFR1; 1970 break; 1971 case 7: 1972 specReg = MISCREG_MVFR0; 1973 break; 1974 case 8: 1975 specReg = MISCREG_FPEXC; 1976 break; 1977 default: 1978 return new Unknown(machInst); 1979 } 1980 if (specReg == MISCREG_FPSCR) { 1981 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 1982 } else { 1983 return new Vmsr(machInst, (IntRegIndex)specReg, rt); 1984 } 1985 } 1986 } else if (l == 0 && c == 1) { 1987 if (bits(a, 2) == 0) { 1988 uint32_t vd = (bits(machInst, 7) << 5) | 1989 (bits(machInst, 19, 16) << 1); 1990 // Handle accessing each single precision half of the vector. 1991 vd += bits(machInst, 21); 1992 const IntRegIndex rt = 1993 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1994 if (bits(machInst, 22) == 1) { 1995 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 1996 rt, bits(machInst, 6, 5)); 1997 } else if (bits(machInst, 5) == 1) { 1998 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 1999 rt, bits(machInst, 6)); 2000 } else if (bits(machInst, 6) == 0) { 2001 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 2002 } else { 2003 return new Unknown(machInst); 2004 } 2005 } else if (bits(b, 1) == 0) { 2006 bool q = bits(machInst, 21); 2007 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2008 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2009 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2010 IntRegIndex rt = (IntRegIndex)(uint32_t) 2011 bits(machInst, 15, 12); 2012 if (q) { 2013 switch (be) { 2014 case 0: 2015 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2016 case 1: 2017 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2018 case 2: 2019 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2020 case 3: 2021 return new Unknown(machInst); 2022 } 2023 } else { 2024 switch (be) { 2025 case 0: 2026 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2027 case 1: 2028 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2029 case 2: 2030 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2031 case 3: 2032 return new Unknown(machInst); 2033 } 2034 } 2035 } 2036 } else if (l == 1 && c == 0) { 2037 if (a == 0) { 2038 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2039 bits(machInst, 7); 2040 const IntRegIndex rt = 2041 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2042 if (bits(machInst, 20) == 1) { 2043 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2044 } else { 2045 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2046 } 2047 } else if (a == 7) { 2048 const IntRegIndex rt = 2049 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2050 uint32_t specReg = bits(machInst, 19, 16); 2051 switch (specReg) { 2052 case 0: 2053 specReg = MISCREG_FPSID; 2054 break; 2055 case 1: 2056 specReg = MISCREG_FPSCR; 2057 break; 2058 case 6: 2059 specReg = MISCREG_MVFR1; 2060 break; 2061 case 7: 2062 specReg = MISCREG_MVFR0; 2063 break; 2064 case 8: 2065 specReg = MISCREG_FPEXC; 2066 break; 2067 default: 2068 return new Unknown(machInst); 2069 } 2070 if (rt == 0xf) { 2071 if (specReg == MISCREG_FPSCR) { 2072 return new VmrsApsrFpscr(machInst); 2073 } else { 2074 return new Unknown(machInst); 2075 } 2076 } else if (specReg == MISCREG_FPSCR) { 2077 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2078 } else { 2079 return new Vmrs(machInst, rt, (IntRegIndex)specReg); 2080 } 2081 } 2082 } else { 2083 uint32_t vd = (bits(machInst, 7) << 5) | 2084 (bits(machInst, 19, 16) << 1); 2085 // Handle indexing into each single precision half of the vector. 2086 vd += bits(machInst, 21); 2087 uint32_t index; 2088 const IntRegIndex rt = 2089 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2090 const bool u = (bits(machInst, 23) == 1); 2091 if (bits(machInst, 22) == 1) { 2092 index = bits(machInst, 6, 5); 2093 if (u) { 2094 return new VmovRegCoreUB(machInst, rt, 2095 (IntRegIndex)vd, index); 2096 } else { 2097 return new VmovRegCoreSB(machInst, rt, 2098 (IntRegIndex)vd, index); 2099 } 2100 } else if (bits(machInst, 5) == 1) { 2101 index = bits(machInst, 6); 2102 if (u) { 2103 return new VmovRegCoreUH(machInst, rt, 2104 (IntRegIndex)vd, index); 2105 } else { 2106 return new VmovRegCoreSH(machInst, rt, 2107 (IntRegIndex)vd, index); 2108 } 2109 } else if (bits(machInst, 6) == 0 && !u) { 2110 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2111 } else { 2112 return new Unknown(machInst); 2113 } 2114 } 2115 return new Unknown(machInst); 2116 } 2117 ''' 2118}}; 2119 2120def format ShortFpTransfer() {{ 2121 decode_block = ''' 2122 return decodeShortFpTransfer(machInst); 2123 ''' 2124}}; 2125 2126let {{ 2127 header_output = ''' 2128 StaticInstPtr 2129 decodeVfpData(ExtMachInst machInst); 2130 ''' 2131 decoder_output = ''' 2132 StaticInstPtr 2133 decodeVfpData(ExtMachInst machInst) 2134 { 2135 const uint32_t opc1 = bits(machInst, 23, 20); 2136 const uint32_t opc2 = bits(machInst, 19, 16); 2137 const uint32_t opc3 = bits(machInst, 7, 6); 2138 //const uint32_t opc4 = bits(machInst, 3, 0); 2139 const bool single = (bits(machInst, 8) == 0); 2140 // Used to select between vcmp and vcmpe. 2141 const bool e = (bits(machInst, 7) == 1); 2142 IntRegIndex vd; 2143 IntRegIndex vm; 2144 IntRegIndex vn; 2145 if (single) { 2146 vd = (IntRegIndex)(bits(machInst, 22) | 2147 (bits(machInst, 15, 12) << 1)); 2148 vm = (IntRegIndex)(bits(machInst, 5) | 2149 (bits(machInst, 3, 0) << 1)); 2150 vn = (IntRegIndex)(bits(machInst, 7) | 2151 (bits(machInst, 19, 16) << 1)); 2152 } else { 2153 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2154 (bits(machInst, 15, 12) << 1)); 2155 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2156 (bits(machInst, 3, 0) << 1)); 2157 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2158 (bits(machInst, 19, 16) << 1)); 2159 } 2160 switch (opc1 & 0xb /* 1011 */) { 2161 case 0x0: 2162 if (bits(machInst, 6) == 0) { 2163 if (single) { 2164 return decodeVfpRegRegRegOp<VmlaS>( 2165 machInst, vd, vn, vm, false); 2166 } else { 2167 return decodeVfpRegRegRegOp<VmlaD>( 2168 machInst, vd, vn, vm, true); 2169 } 2170 } else { 2171 if (single) { 2172 return decodeVfpRegRegRegOp<VmlsS>( 2173 machInst, vd, vn, vm, false); 2174 } else { 2175 return decodeVfpRegRegRegOp<VmlsD>( 2176 machInst, vd, vn, vm, true); 2177 } 2178 } 2179 case 0x1: 2180 if (bits(machInst, 6) == 1) { 2181 if (single) { 2182 return decodeVfpRegRegRegOp<VnmlaS>( 2183 machInst, vd, vn, vm, false); 2184 } else { 2185 return decodeVfpRegRegRegOp<VnmlaD>( 2186 machInst, vd, vn, vm, true); 2187 } 2188 } else { 2189 if (single) { 2190 return decodeVfpRegRegRegOp<VnmlsS>( 2191 machInst, vd, vn, vm, false); 2192 } else { 2193 return decodeVfpRegRegRegOp<VnmlsD>( 2194 machInst, vd, vn, vm, true); 2195 } 2196 } 2197 case 0x2: 2198 if ((opc3 & 0x1) == 0) { 2199 if (single) { 2200 return decodeVfpRegRegRegOp<VmulS>( 2201 machInst, vd, vn, vm, false); 2202 } else { 2203 return decodeVfpRegRegRegOp<VmulD>( 2204 machInst, vd, vn, vm, true); 2205 } 2206 } else { 2207 if (single) { 2208 return decodeVfpRegRegRegOp<VnmulS>( 2209 machInst, vd, vn, vm, false); 2210 } else { 2211 return decodeVfpRegRegRegOp<VnmulD>( 2212 machInst, vd, vn, vm, true); 2213 } 2214 } 2215 case 0x3: 2216 if ((opc3 & 0x1) == 0) { 2217 if (single) { 2218 return decodeVfpRegRegRegOp<VaddS>( 2219 machInst, vd, vn, vm, false); 2220 } else { 2221 return decodeVfpRegRegRegOp<VaddD>( 2222 machInst, vd, vn, vm, true); 2223 } 2224 } else { 2225 if (single) { 2226 return decodeVfpRegRegRegOp<VsubS>( 2227 machInst, vd, vn, vm, false); 2228 } else { 2229 return decodeVfpRegRegRegOp<VsubD>( 2230 machInst, vd, vn, vm, true); 2231 } 2232 } 2233 case 0x8: 2234 if ((opc3 & 0x1) == 0) { 2235 if (single) { 2236 return decodeVfpRegRegRegOp<VdivS>( 2237 machInst, vd, vn, vm, false); 2238 } else { 2239 return decodeVfpRegRegRegOp<VdivD>( 2240 machInst, vd, vn, vm, true); 2241 } 2242 } 2243 break; 2244 case 0xb: 2245 if ((opc3 & 0x1) == 0) { 2246 const uint32_t baseImm = 2247 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2248 if (single) { 2249 uint32_t imm = vfp_modified_imm(baseImm, false); 2250 return decodeVfpRegImmOp<VmovImmS>( 2251 machInst, vd, imm, false); 2252 } else { 2253 uint64_t imm = vfp_modified_imm(baseImm, true); 2254 return decodeVfpRegImmOp<VmovImmD>( 2255 machInst, vd, imm, true); 2256 } 2257 } 2258 switch (opc2) { 2259 case 0x0: 2260 if (opc3 == 1) { 2261 if (single) { 2262 return decodeVfpRegRegOp<VmovRegS>( 2263 machInst, vd, vm, false); 2264 } else { 2265 return decodeVfpRegRegOp<VmovRegD>( 2266 machInst, vd, vm, true); 2267 } 2268 } else { 2269 if (single) { 2270 return decodeVfpRegRegOp<VabsS>( 2271 machInst, vd, vm, false); 2272 } else { 2273 return decodeVfpRegRegOp<VabsD>( 2274 machInst, vd, vm, true); 2275 } 2276 } 2277 case 0x1: 2278 if (opc3 == 1) { 2279 if (single) { 2280 return decodeVfpRegRegOp<VnegS>( 2281 machInst, vd, vm, false); 2282 } else { 2283 return decodeVfpRegRegOp<VnegD>( 2284 machInst, vd, vm, true); 2285 } 2286 } else { 2287 if (single) { 2288 return decodeVfpRegRegOp<VsqrtS>( 2289 machInst, vd, vm, false); 2290 } else { 2291 return decodeVfpRegRegOp<VsqrtD>( 2292 machInst, vd, vm, true); 2293 } 2294 } 2295 case 0x2: 2296 case 0x3: 2297 { 2298 const bool toHalf = bits(machInst, 16); 2299 const bool top = bits(machInst, 7); 2300 if (top) { 2301 if (toHalf) { 2302 return new VcvtFpSFpHT(machInst, vd, vm); 2303 } else { 2304 return new VcvtFpHTFpS(machInst, vd, vm); 2305 } 2306 } else { 2307 if (toHalf) { 2308 return new VcvtFpSFpHB(machInst, vd, vm); 2309 } else { 2310 return new VcvtFpHBFpS(machInst, vd, vm); 2311 } 2312 } 2313 } 2314 case 0x4: 2315 if (single) { 2316 if (e) { 2317 return new VcmpeS(machInst, vd, vm); 2318 } else { 2319 return new VcmpS(machInst, vd, vm); 2320 } 2321 } else { 2322 if (e) { 2323 return new VcmpeD(machInst, vd, vm); 2324 } else { 2325 return new VcmpD(machInst, vd, vm); 2326 } 2327 } 2328 case 0x5: 2329 if (single) { 2330 if (e) { 2331 return new VcmpeZeroS(machInst, vd, 0); 2332 } else { 2333 return new VcmpZeroS(machInst, vd, 0); 2334 } 2335 } else { 2336 if (e) { 2337 return new VcmpeZeroD(machInst, vd, 0); 2338 } else { 2339 return new VcmpZeroD(machInst, vd, 0); 2340 } 2341 } 2342 case 0x7: 2343 if (opc3 == 0x3) { 2344 if (single) { 2345 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2346 (bits(machInst, 15, 12) << 1)); 2347 return new VcvtFpSFpD(machInst, vd, vm); 2348 } else { 2349 vd = (IntRegIndex)(bits(machInst, 22) | 2350 (bits(machInst, 15, 12) << 1)); 2351 return new VcvtFpDFpS(machInst, vd, vm); 2352 } 2353 } 2354 break; 2355 case 0x8: 2356 if (bits(machInst, 7) == 0) { 2357 if (single) { 2358 return new VcvtUIntFpS(machInst, vd, vm); 2359 } else { 2360 vm = (IntRegIndex)(bits(machInst, 5) | 2361 (bits(machInst, 3, 0) << 1)); 2362 return new VcvtUIntFpD(machInst, vd, vm); 2363 } 2364 } else { 2365 if (single) { 2366 return new VcvtSIntFpS(machInst, vd, vm); 2367 } else { 2368 vm = (IntRegIndex)(bits(machInst, 5) | 2369 (bits(machInst, 3, 0) << 1)); 2370 return new VcvtSIntFpD(machInst, vd, vm); 2371 } 2372 } 2373 case 0xa: 2374 { 2375 const bool half = (bits(machInst, 7) == 0); 2376 const uint32_t imm = bits(machInst, 5) | 2377 (bits(machInst, 3, 0) << 1); 2378 const uint32_t size = 2379 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2380 if (single) { 2381 if (half) { 2382 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2383 } else { 2384 return new VcvtSFixedFpS(machInst, vd, vd, size); 2385 } 2386 } else { 2387 if (half) { 2388 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2389 } else { 2390 return new VcvtSFixedFpD(machInst, vd, vd, size); 2391 } 2392 } 2393 } 2394 case 0xb: 2395 { 2396 const bool half = (bits(machInst, 7) == 0); 2397 const uint32_t imm = bits(machInst, 5) | 2398 (bits(machInst, 3, 0) << 1); 2399 const uint32_t size = 2400 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2401 if (single) { 2402 if (half) { 2403 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2404 } else { 2405 return new VcvtUFixedFpS(machInst, vd, vd, size); 2406 } 2407 } else { 2408 if (half) { 2409 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2410 } else { 2411 return new VcvtUFixedFpD(machInst, vd, vd, size); 2412 } 2413 } 2414 } 2415 case 0xc: 2416 if (bits(machInst, 7) == 0) { 2417 if (single) { 2418 return new VcvtFpUIntSR(machInst, vd, vm); 2419 } else { 2420 vd = (IntRegIndex)(bits(machInst, 22) | 2421 (bits(machInst, 15, 12) << 1)); 2422 return new VcvtFpUIntDR(machInst, vd, vm); 2423 } 2424 } else { 2425 if (single) { 2426 return new VcvtFpUIntS(machInst, vd, vm); 2427 } else { 2428 vd = (IntRegIndex)(bits(machInst, 22) | 2429 (bits(machInst, 15, 12) << 1)); 2430 return new VcvtFpUIntD(machInst, vd, vm); 2431 } 2432 } 2433 case 0xd: 2434 if (bits(machInst, 7) == 0) { 2435 if (single) { 2436 return new VcvtFpSIntSR(machInst, vd, vm); 2437 } else { 2438 vd = (IntRegIndex)(bits(machInst, 22) | 2439 (bits(machInst, 15, 12) << 1)); 2440 return new VcvtFpSIntDR(machInst, vd, vm); 2441 } 2442 } else { 2443 if (single) { 2444 return new VcvtFpSIntS(machInst, vd, vm); 2445 } else { 2446 vd = (IntRegIndex)(bits(machInst, 22) | 2447 (bits(machInst, 15, 12) << 1)); 2448 return new VcvtFpSIntD(machInst, vd, vm); 2449 } 2450 } 2451 case 0xe: 2452 { 2453 const bool half = (bits(machInst, 7) == 0); 2454 const uint32_t imm = bits(machInst, 5) | 2455 (bits(machInst, 3, 0) << 1); 2456 const uint32_t size = 2457 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2458 if (single) { 2459 if (half) { 2460 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2461 } else { 2462 return new VcvtFpSFixedS(machInst, vd, vd, size); 2463 } 2464 } else { 2465 if (half) { 2466 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2467 } else { 2468 return new VcvtFpSFixedD(machInst, vd, vd, size); 2469 } 2470 } 2471 } 2472 case 0xf: 2473 { 2474 const bool half = (bits(machInst, 7) == 0); 2475 const uint32_t imm = bits(machInst, 5) | 2476 (bits(machInst, 3, 0) << 1); 2477 const uint32_t size = 2478 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2479 if (single) { 2480 if (half) { 2481 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2482 } else { 2483 return new VcvtFpUFixedS(machInst, vd, vd, size); 2484 } 2485 } else { 2486 if (half) { 2487 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2488 } else { 2489 return new VcvtFpUFixedD(machInst, vd, vd, size); 2490 } 2491 } 2492 } 2493 } 2494 break; 2495 } 2496 return new Unknown(machInst); 2497 } 2498 ''' 2499}}; 2500 2501def format VfpData() {{ 2502 decode_block = ''' 2503 return decodeVfpData(machInst); 2504 ''' 2505}}; 2506