fp.isa revision 10037
19665Sandreas.hansson@arm.com// -*- mode:c++ -*- 29665Sandreas.hansson@arm.com 39665Sandreas.hansson@arm.com// Copyright (c) 2010-2011 ARM Limited 49665Sandreas.hansson@arm.com// All rights reserved 59665Sandreas.hansson@arm.com// 69665Sandreas.hansson@arm.com// The license below extends only to copyright in the software and shall 79665Sandreas.hansson@arm.com// not be construed as granting a license to any other intellectual 89665Sandreas.hansson@arm.com// property including but not limited to intellectual property relating 99665Sandreas.hansson@arm.com// to a hardware implementation of the functionality of the software 109665Sandreas.hansson@arm.com// licensed hereunder. You may use the software subject to the license 119665Sandreas.hansson@arm.com// terms below provided that you ensure that this notice is replicated 129665Sandreas.hansson@arm.com// unmodified and in its entirety in all distributions of the software, 135353Svilas.sridharan@gmail.com// modified or unmodified, in source code or in binary form. 143395Shsul@eecs.umich.edu// 153395Shsul@eecs.umich.edu// Copyright (c) 2007-2008 The Florida State University 163395Shsul@eecs.umich.edu// All rights reserved. 173395Shsul@eecs.umich.edu// 183395Shsul@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 193395Shsul@eecs.umich.edu// modification, are permitted provided that the following conditions are 203395Shsul@eecs.umich.edu// met: redistributions of source code must retain the above copyright 213395Shsul@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 223395Shsul@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 233395Shsul@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 243395Shsul@eecs.umich.edu// documentation and/or other materials provided with the distribution; 253395Shsul@eecs.umich.edu// neither the name of the copyright holders nor the names of its 263395Shsul@eecs.umich.edu// contributors may be used to endorse or promote products derived from 273395Shsul@eecs.umich.edu// this software without specific prior written permission. 283395Shsul@eecs.umich.edu// 293395Shsul@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 303395Shsul@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 313395Shsul@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 323395Shsul@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 333395Shsul@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 343395Shsul@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 353395Shsul@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 363395Shsul@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 373395Shsul@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 383395Shsul@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 393395Shsul@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 403395Shsul@eecs.umich.edu// 4113774Sandreas.sandberg@arm.com// Authors: Stephen Hines 4213774Sandreas.sandberg@arm.com 4313774Sandreas.sandberg@arm.com//////////////////////////////////////////////////////////////////// 448920Snilay@cs.wisc.edu// 458920Snilay@cs.wisc.edu// Floating Point operate instructions 468920Snilay@cs.wisc.edu// 477025SBrad.Beckmann@amd.com 4813774Sandreas.sandberg@arm.comoutput header {{ 4913774Sandreas.sandberg@arm.com 5013774Sandreas.sandberg@arm.com template<template <typename T> class Base> 5113774Sandreas.sandberg@arm.com StaticInstPtr 5213774Sandreas.sandberg@arm.com newNeonMemInst(const unsigned size, 5310747SChris.Emmons@arm.com const ExtMachInst &machInst, 549520SAndreas.Sandberg@ARM.com const RegIndex dest, const RegIndex ra, 559520SAndreas.Sandberg@ARM.com const uint32_t imm, const unsigned extraMemFlags) 569520SAndreas.Sandberg@ARM.com { 579520SAndreas.Sandberg@ARM.com switch (size) { 5813432Spau.cabre@metempsy.com case 0: 5913432Spau.cabre@metempsy.com return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags); 6013432Spau.cabre@metempsy.com case 1: 6113432Spau.cabre@metempsy.com return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags); 629665Sandreas.hansson@arm.com case 2: 639665Sandreas.hansson@arm.com return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags); 649665Sandreas.hansson@arm.com case 3: 659665Sandreas.hansson@arm.com return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags); 6611238Sandreas.sandberg@arm.com default: 6711238Sandreas.sandberg@arm.com panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 6811238Sandreas.sandberg@arm.com } 6911238Sandreas.sandberg@arm.com } 7011688Sandreas.hansson@arm.com 7111688Sandreas.hansson@arm.com template<template <typename T> class Base> 7211688Sandreas.hansson@arm.com StaticInstPtr 7311688Sandreas.hansson@arm.com newNeonMixInst(const unsigned size, 748920Snilay@cs.wisc.edu const ExtMachInst &machInst, 759827Sakash.bagdia@arm.com const RegIndex dest, const RegIndex op1, 769827Sakash.bagdia@arm.com const uint32_t step) 779827Sakash.bagdia@arm.com { 789827Sakash.bagdia@arm.com switch (size) { 799790Sakash.bagdia@arm.com case 0: 809790Sakash.bagdia@arm.com return new Base<uint8_t>(machInst, dest, op1, step); 819790Sakash.bagdia@arm.com case 1: 829790Sakash.bagdia@arm.com return new Base<uint16_t>(machInst, dest, op1, step); 8311688Sandreas.hansson@arm.com case 2: 8411688Sandreas.hansson@arm.com return new Base<uint32_t>(machInst, dest, op1, step); 8511688Sandreas.hansson@arm.com case 3: 8611688Sandreas.hansson@arm.com return new Base<uint64_t>(machInst, dest, op1, step); 8711688Sandreas.hansson@arm.com default: 8811837Swendy.elsasser@arm.com panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 8911688Sandreas.hansson@arm.com } 9011688Sandreas.hansson@arm.com } 9111688Sandreas.hansson@arm.com 9211688Sandreas.hansson@arm.com}}; 9311688Sandreas.hansson@arm.com 9411688Sandreas.hansson@arm.comlet {{ 9511688Sandreas.hansson@arm.com header_output = ''' 9611688Sandreas.hansson@arm.com StaticInstPtr 9711688Sandreas.hansson@arm.com decodeNeonMem(ExtMachInst machInst); 9811688Sandreas.hansson@arm.com 9911688Sandreas.hansson@arm.com StaticInstPtr 10011688Sandreas.hansson@arm.com decodeNeonData(ExtMachInst machInst); 10111688Sandreas.hansson@arm.com ''' 10211688Sandreas.hansson@arm.com 10311688Sandreas.hansson@arm.com decoder_output = ''' 10411688Sandreas.hansson@arm.com StaticInstPtr 10511688Sandreas.hansson@arm.com decodeNeonMem(ExtMachInst machInst) 10611688Sandreas.hansson@arm.com { 10711688Sandreas.hansson@arm.com const uint32_t b = bits(machInst, 11, 8); 10811688Sandreas.hansson@arm.com const bool single = bits(machInst, 23); 10911688Sandreas.hansson@arm.com const bool singleAll = single && (bits(b, 3, 2) == 3); 11011688Sandreas.hansson@arm.com const bool load = bits(machInst, 21); 11111688Sandreas.hansson@arm.com 11211688Sandreas.hansson@arm.com unsigned width = 0; 11311688Sandreas.hansson@arm.com 11411688Sandreas.hansson@arm.com if (single) { 11511688Sandreas.hansson@arm.com width = bits(b, 1, 0) + 1; 11611688Sandreas.hansson@arm.com } else { 11711688Sandreas.hansson@arm.com switch (bits(b, 3, 1)) { 11811688Sandreas.hansson@arm.com case 0x0: width = 4; 11911688Sandreas.hansson@arm.com break; 12011688Sandreas.hansson@arm.com case 0x1: width = (b & 0x1) ? 2 : 1; 12111688Sandreas.hansson@arm.com break; 12211688Sandreas.hansson@arm.com case 0x2: width = 3; 12311688Sandreas.hansson@arm.com break; 12411688Sandreas.hansson@arm.com case 0x3: width = 1; 12511688Sandreas.hansson@arm.com break; 12611688Sandreas.hansson@arm.com case 0x4: width = 2; 12711688Sandreas.hansson@arm.com break; 12811688Sandreas.hansson@arm.com case 0x5: 12911688Sandreas.hansson@arm.com if ((b & 0x1) == 0) { 13011688Sandreas.hansson@arm.com width = 1; 13111688Sandreas.hansson@arm.com break; 13211688Sandreas.hansson@arm.com } 13311688Sandreas.hansson@arm.com // Fall through on purpose. 13411688Sandreas.hansson@arm.com default: 13511688Sandreas.hansson@arm.com return new Unknown(machInst); 13613357Sciro.santilli@arm.com } 13713357Sciro.santilli@arm.com } 13813357Sciro.santilli@arm.com assert(width > 0 && width <= 4); 13913357Sciro.santilli@arm.com 14013357Sciro.santilli@arm.com const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0); 14113357Sciro.santilli@arm.com const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16); 14213357Sciro.santilli@arm.com const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) | 14313357Sciro.santilli@arm.com bits(machInst, 22) << 4); 14411688Sandreas.hansson@arm.com const uint32_t type = bits(machInst, 11, 8); 14511688Sandreas.hansson@arm.com uint32_t size = 0; 14611688Sandreas.hansson@arm.com uint32_t align = TLB::MustBeOne; 14711688Sandreas.hansson@arm.com unsigned inc = 1; 14811688Sandreas.hansson@arm.com unsigned regs = 1; 14911688Sandreas.hansson@arm.com unsigned lane = 0; 15011688Sandreas.hansson@arm.com if (single) { 15111688Sandreas.hansson@arm.com if (singleAll) { 15211688Sandreas.hansson@arm.com size = bits(machInst, 7, 6); 15311688Sandreas.hansson@arm.com bool t = bits(machInst, 5); 15411995Sgabeblack@google.com align = size | TLB::AllowUnaligned; 15511688Sandreas.hansson@arm.com if (width == 1) { 15611688Sandreas.hansson@arm.com regs = t ? 2 : 1; 15713432Spau.cabre@metempsy.com inc = 1; 15813432Spau.cabre@metempsy.com } else { 15913432Spau.cabre@metempsy.com regs = width; 16013432Spau.cabre@metempsy.com inc = t ? 2 : 1; 16113432Spau.cabre@metempsy.com } 16213432Spau.cabre@metempsy.com switch (width) { 16313432Spau.cabre@metempsy.com case 1: 16413432Spau.cabre@metempsy.com case 2: 16513432Spau.cabre@metempsy.com if (bits(machInst, 4)) 16611688Sandreas.hansson@arm.com align = size + width - 1; 1679789Sakash.bagdia@arm.com break; 1689789Sakash.bagdia@arm.com case 3: 1699789Sakash.bagdia@arm.com break; 1709800Snilay@cs.wisc.edu case 4: 1719800Snilay@cs.wisc.edu if (size == 3) { 1729800Snilay@cs.wisc.edu if (bits(machInst, 4) == 0) 1739800Snilay@cs.wisc.edu return new Unknown(machInst); 1749800Snilay@cs.wisc.edu size = 2; 17511251Sradhika.jagtap@ARM.com align = 0x4; 17611251Sradhika.jagtap@ARM.com } else if (size == 2) { 17711251Sradhika.jagtap@ARM.com if (bits(machInst, 4)) 17811251Sradhika.jagtap@ARM.com align = 0x3; 17911251Sradhika.jagtap@ARM.com } else { 18011251Sradhika.jagtap@ARM.com if (bits(machInst, 4)) 18111251Sradhika.jagtap@ARM.com align = size + 2; 18211251Sradhika.jagtap@ARM.com } 18311251Sradhika.jagtap@ARM.com break; 18411251Sradhika.jagtap@ARM.com } 18511251Sradhika.jagtap@ARM.com } else { 18611251Sradhika.jagtap@ARM.com size = bits(machInst, 11, 10); 18711251Sradhika.jagtap@ARM.com align = size | TLB::AllowUnaligned; 1889800Snilay@cs.wisc.edu regs = width; 18910037SARM gem5 Developers unsigned indexAlign = bits(machInst, 7, 4); 19010037SARM gem5 Developers // If width is 1, inc is always 1. That's overridden later. 19110037SARM gem5 Developers switch (size) { 19211626Smichael.lebeane@amd.com case 0: 19311626Smichael.lebeane@amd.com inc = 1; 19411626Smichael.lebeane@amd.com lane = bits(indexAlign, 3, 1); 19511703Smichael.lebeane@amd.com break; 19611703Smichael.lebeane@amd.com case 1: 19711626Smichael.lebeane@amd.com inc = bits(indexAlign, 1) ? 2 : 1; 19811626Smichael.lebeane@amd.com lane = bits(indexAlign, 3, 2); 19911626Smichael.lebeane@amd.com break; 20011626Smichael.lebeane@amd.com case 2: 20111626Smichael.lebeane@amd.com inc = bits(indexAlign, 2) ? 2 : 1; 20211626Smichael.lebeane@amd.com lane = bits(indexAlign, 3); 20311626Smichael.lebeane@amd.com break; 20411626Smichael.lebeane@amd.com } 20511626Smichael.lebeane@amd.com // Override inc for width of 1. 20611626Smichael.lebeane@amd.com if (width == 1) { 20711626Smichael.lebeane@amd.com inc = 1; 20811626Smichael.lebeane@amd.com } 20911626Smichael.lebeane@amd.com switch (width) { 21011626Smichael.lebeane@amd.com case 1: 21111626Smichael.lebeane@amd.com switch (size) { 21211626Smichael.lebeane@amd.com case 0: 21311626Smichael.lebeane@amd.com break; 21411626Smichael.lebeane@amd.com case 1: 21511626Smichael.lebeane@amd.com if (bits(indexAlign, 0)) 21611626Smichael.lebeane@amd.com align = 1; 21711626Smichael.lebeane@amd.com break; 21811626Smichael.lebeane@amd.com case 2: 21911626Smichael.lebeane@amd.com if (bits(indexAlign, 1, 0)) 22011626Smichael.lebeane@amd.com align = 2; 22111626Smichael.lebeane@amd.com break; 22211626Smichael.lebeane@amd.com } 22311626Smichael.lebeane@amd.com break; 22411626Smichael.lebeane@amd.com case 2: 22511626Smichael.lebeane@amd.com if (bits(indexAlign, 0)) 22611626Smichael.lebeane@amd.com align = size + 1; 2278920Snilay@cs.wisc.edu break; 2288920Snilay@cs.wisc.edu case 3: 2298920Snilay@cs.wisc.edu break; 2308920Snilay@cs.wisc.edu case 4: 2318920Snilay@cs.wisc.edu switch (size) { 2328920Snilay@cs.wisc.edu case 0: 23310159Sgedare@rtems.org case 1: 23410159Sgedare@rtems.org if (bits(indexAlign, 0)) 2358920Snilay@cs.wisc.edu align = size + 2; 2368920Snilay@cs.wisc.edu break; 2378920Snilay@cs.wisc.edu case 2: 2388920Snilay@cs.wisc.edu if (bits(indexAlign, 0)) 2398920Snilay@cs.wisc.edu align = bits(indexAlign, 1, 0) + 2; 2408920Snilay@cs.wisc.edu break; 2418920Snilay@cs.wisc.edu } 2428920Snilay@cs.wisc.edu break; 2438920Snilay@cs.wisc.edu } 24410757SCurtis.Dunham@arm.com } 24510757SCurtis.Dunham@arm.com if (size == 0x3) { 24610757SCurtis.Dunham@arm.com return new Unknown(machInst); 2476776SBrad.Beckmann@amd.com } 2489800Snilay@cs.wisc.edu } else { 2499800Snilay@cs.wisc.edu size = bits(machInst, 7, 6); 2509800Snilay@cs.wisc.edu align = bits(machInst, 5, 4); 2519800Snilay@cs.wisc.edu if (align == 0) { 2529800Snilay@cs.wisc.edu // @align wasn't specified, so alignment can be turned off. 25310608Sdam.sunwoo@arm.com align = size | TLB::AllowUnaligned; 25410608Sdam.sunwoo@arm.com } else { 25510608Sdam.sunwoo@arm.com align = align + 2; 25610608Sdam.sunwoo@arm.com } 25710608Sdam.sunwoo@arm.com switch (width) { 2589800Snilay@cs.wisc.edu case 1: 2598920Snilay@cs.wisc.edu switch (type) { 2608920Snilay@cs.wisc.edu case 0x7: regs = 1; 2618920Snilay@cs.wisc.edu break; 2628920Snilay@cs.wisc.edu case 0xa: regs = 2; 2639357Sandreas.hansson@arm.com break; 2648920Snilay@cs.wisc.edu case 0x6: regs = 3; 2658920Snilay@cs.wisc.edu break; 2668920Snilay@cs.wisc.edu case 0x2: regs = 4; 2678920Snilay@cs.wisc.edu break; 2688920Snilay@cs.wisc.edu default: 2698920Snilay@cs.wisc.edu return new Unknown(machInst); 2708920Snilay@cs.wisc.edu } 2718920Snilay@cs.wisc.edu break; 2728920Snilay@cs.wisc.edu case 2: 2738920Snilay@cs.wisc.edu // Regs doesn't behave exactly as it does in the manual 2748920Snilay@cs.wisc.edu // because they loop over regs registers twice and we break 2758920Snilay@cs.wisc.edu // it down in the macroop. 2768920Snilay@cs.wisc.edu switch (type) { 2778920Snilay@cs.wisc.edu case 0x8: regs = 2; inc = 1; 2788920Snilay@cs.wisc.edu break; 27911995Sgabeblack@google.com case 0x9: regs = 2; inc = 2; 2808920Snilay@cs.wisc.edu break; 2813395Shsul@eecs.umich.edu case 0x3: regs = 4; inc = 2; 2825361Srstrong@cs.ucsd.edu break; 2838920Snilay@cs.wisc.edu default: 2848920Snilay@cs.wisc.edu return new Unknown(machInst); 2858920Snilay@cs.wisc.edu } 2869151Satgutier@umich.edu break; 2879151Satgutier@umich.edu case 3: 2889151Satgutier@umich.edu regs = 3; 2899151Satgutier@umich.edu switch (type) { 2909151Satgutier@umich.edu case 0x4: inc = 1; 2919151Satgutier@umich.edu break; 2929562Ssaidi@eecs.umich.edu case 0x5: inc = 2;; 2938920Snilay@cs.wisc.edu break; 2948920Snilay@cs.wisc.edu default: 2958920Snilay@cs.wisc.edu return new Unknown(machInst); 2968920Snilay@cs.wisc.edu } 2978920Snilay@cs.wisc.edu break; 2988920Snilay@cs.wisc.edu case 4: 2998920Snilay@cs.wisc.edu regs = 4; 3008920Snilay@cs.wisc.edu switch (type) { 3018920Snilay@cs.wisc.edu case 0: inc = 1; 3028920Snilay@cs.wisc.edu break; 3038920Snilay@cs.wisc.edu case 1: inc = 2; 3048920Snilay@cs.wisc.edu break; 3058920Snilay@cs.wisc.edu default: 3068920Snilay@cs.wisc.edu return new Unknown(machInst); 3078920Snilay@cs.wisc.edu } 3088920Snilay@cs.wisc.edu break; 3098920Snilay@cs.wisc.edu } 31010037SARM gem5 Developers } 31110037SARM gem5 Developers 31210037SARM gem5 Developers if (load) { 31310037SARM gem5 Developers // Load instructions. 31410037SARM gem5 Developers if (single) { 31510037SARM gem5 Developers return new VldSingle(machInst, singleAll, width, rn, vd, 31610037SARM gem5 Developers regs, inc, size, align, rm, lane); 31710037SARM gem5 Developers } else { 3188920Snilay@cs.wisc.edu return new VldMult(machInst, width, rn, vd, 3198920Snilay@cs.wisc.edu regs, inc, size, align, rm); 3208920Snilay@cs.wisc.edu } 3218920Snilay@cs.wisc.edu } else { 3228920Snilay@cs.wisc.edu // Store instructions. 3238920Snilay@cs.wisc.edu if (single) { 3248920Snilay@cs.wisc.edu if (singleAll) { 3258920Snilay@cs.wisc.edu return new Unknown(machInst); 32610803Sbrandon.potter@amd.com } else { 32710803Sbrandon.potter@amd.com return new VstSingle(machInst, false, width, rn, vd, 3288920Snilay@cs.wisc.edu regs, inc, size, align, rm, lane); 3298920Snilay@cs.wisc.edu } 3308920Snilay@cs.wisc.edu } else { 3318920Snilay@cs.wisc.edu return new VstMult(machInst, width, rn, vd, 3328920Snilay@cs.wisc.edu regs, inc, size, align, rm); 3338920Snilay@cs.wisc.edu } 3348920Snilay@cs.wisc.edu } 3358920Snilay@cs.wisc.edu return new Unknown(machInst); 33613774Sandreas.sandberg@arm.com } 33711688Sandreas.hansson@arm.com ''' 3388920Snilay@cs.wisc.edu 3398920Snilay@cs.wisc.edu decoder_output += ''' 3408920Snilay@cs.wisc.edu static StaticInstPtr 3418920Snilay@cs.wisc.edu decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 3428920Snilay@cs.wisc.edu { 3438920Snilay@cs.wisc.edu const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 34410747SChris.Emmons@arm.com const uint32_t a = bits(machInst, 11, 8); 34513731Sandreas.sandberg@arm.com const bool b = bits(machInst, 4); 34613731Sandreas.sandberg@arm.com const uint32_t c = bits(machInst, 21, 20); 34713731Sandreas.sandberg@arm.com const IntRegIndex vd = 3488920Snilay@cs.wisc.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 3498920Snilay@cs.wisc.edu (bits(machInst, 22) << 4))); 3508920Snilay@cs.wisc.edu const IntRegIndex vn = 3518920Snilay@cs.wisc.edu (IntRegIndex)(2 * (bits(machInst, 19, 16) | 3528920Snilay@cs.wisc.edu (bits(machInst, 7) << 4))); 3538920Snilay@cs.wisc.edu const IntRegIndex vm = 3548920Snilay@cs.wisc.edu (IntRegIndex)(2 * (bits(machInst, 3, 0) | 3558920Snilay@cs.wisc.edu (bits(machInst, 5) << 4))); 35611238Sandreas.sandberg@arm.com const unsigned size = bits(machInst, 21, 20); 35711238Sandreas.sandberg@arm.com const bool q = bits(machInst, 6); 35811238Sandreas.sandberg@arm.com if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1))) 3598920Snilay@cs.wisc.edu return new Unknown(machInst); 36011238Sandreas.sandberg@arm.com switch (a) { 36111238Sandreas.sandberg@arm.com case 0x0: 3629539Satgutier@umich.edu if (b) { 3639539Satgutier@umich.edu if (u) { 3649539Satgutier@umich.edu return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 36512079Sgedare@rtems.org q, size, machInst, vd, vn, vm); 36612079Sgedare@rtems.org } else { 3679935Sdam.sunwoo@arm.com return decodeNeonSThreeReg<VqaddSD, VqaddSQ>( 3689935Sdam.sunwoo@arm.com q, size, machInst, vd, vn, vm); 3699935Sdam.sunwoo@arm.com } 3709935Sdam.sunwoo@arm.com } else { 3718920Snilay@cs.wisc.edu if (size == 3) 3728920Snilay@cs.wisc.edu return new Unknown(machInst); 3738920Snilay@cs.wisc.edu return decodeNeonUSThreeReg<VhaddD, VhaddQ>( 3748920Snilay@cs.wisc.edu q, u, size, machInst, vd, vn, vm); 3758920Snilay@cs.wisc.edu } 3768920Snilay@cs.wisc.edu case 0x1: 3778920Snilay@cs.wisc.edu if (!b) { 3788920Snilay@cs.wisc.edu return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>( 3798920Snilay@cs.wisc.edu q, u, size, machInst, vd, vn, vm); 3808920Snilay@cs.wisc.edu } else { 3818920Snilay@cs.wisc.edu if (u) { 3828920Snilay@cs.wisc.edu switch (c) { 3838956Sjayneel@cs.wisc.edu case 0: 3848956Sjayneel@cs.wisc.edu if (q) { 3858956Sjayneel@cs.wisc.edu return new VeorQ<uint64_t>(machInst, vd, vn, vm); 3868956Sjayneel@cs.wisc.edu } else { 38710697SCurtis.Dunham@arm.com return new VeorD<uint64_t>(machInst, vd, vn, vm); 38810697SCurtis.Dunham@arm.com } 38910594Sgabeblack@google.com case 1: 39010594Sgabeblack@google.com if (q) { 39110594Sgabeblack@google.com return new VbslQ<uint64_t>(machInst, vd, vn, vm); 39210594Sgabeblack@google.com } else { 39310594Sgabeblack@google.com return new VbslD<uint64_t>(machInst, vd, vn, vm); 39410594Sgabeblack@google.com } 39510594Sgabeblack@google.com case 2: 39610594Sgabeblack@google.com if (q) { 397 return new VbitQ<uint64_t>(machInst, vd, vn, vm); 398 } else { 399 return new VbitD<uint64_t>(machInst, vd, vn, vm); 400 } 401 case 3: 402 if (q) { 403 return new VbifQ<uint64_t>(machInst, vd, vn, vm); 404 } else { 405 return new VbifD<uint64_t>(machInst, vd, vn, vm); 406 } 407 } 408 } else { 409 switch (c) { 410 case 0: 411 if (q) { 412 return new VandQ<uint64_t>(machInst, vd, vn, vm); 413 } else { 414 return new VandD<uint64_t>(machInst, vd, vn, vm); 415 } 416 case 1: 417 if (q) { 418 return new VbicQ<uint64_t>(machInst, vd, vn, vm); 419 } else { 420 return new VbicD<uint64_t>(machInst, vd, vn, vm); 421 } 422 case 2: 423 if (vn == vm) { 424 if (q) { 425 return new VmovQ<uint64_t>( 426 machInst, vd, vn, vm); 427 } else { 428 return new VmovD<uint64_t>( 429 machInst, vd, vn, vm); 430 } 431 } else { 432 if (q) { 433 return new VorrQ<uint64_t>( 434 machInst, vd, vn, vm); 435 } else { 436 return new VorrD<uint64_t>( 437 machInst, vd, vn, vm); 438 } 439 } 440 case 3: 441 if (q) { 442 return new VornQ<uint64_t>( 443 machInst, vd, vn, vm); 444 } else { 445 return new VornD<uint64_t>( 446 machInst, vd, vn, vm); 447 } 448 } 449 } 450 } 451 case 0x2: 452 if (b) { 453 if (u) { 454 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 455 q, size, machInst, vd, vn, vm); 456 } else { 457 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 458 q, size, machInst, vd, vn, vm); 459 } 460 } else { 461 if (size == 3) 462 return new Unknown(machInst); 463 return decodeNeonUSThreeReg<VhsubD, VhsubQ>( 464 q, u, size, machInst, vd, vn, vm); 465 } 466 case 0x3: 467 if (b) { 468 return decodeNeonUSThreeReg<VcgeD, VcgeQ>( 469 q, u, size, machInst, vd, vn, vm); 470 } else { 471 return decodeNeonUSThreeReg<VcgtD, VcgtQ>( 472 q, u, size, machInst, vd, vn, vm); 473 } 474 case 0x4: 475 if (b) { 476 if (u) { 477 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>( 478 q, size, machInst, vd, vm, vn); 479 } else { 480 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>( 481 q, size, machInst, vd, vm, vn); 482 } 483 } else { 484 return decodeNeonUSThreeReg<VshlD, VshlQ>( 485 q, u, size, machInst, vd, vm, vn); 486 } 487 case 0x5: 488 if (b) { 489 if (u) { 490 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>( 491 q, size, machInst, vd, vm, vn); 492 } else { 493 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>( 494 q, size, machInst, vd, vm, vn); 495 } 496 } else { 497 return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 498 q, u, size, machInst, vd, vm, vn); 499 } 500 case 0x6: 501 if (b) { 502 return decodeNeonUSThreeReg<VminD, VminQ>( 503 q, u, size, machInst, vd, vn, vm); 504 } else { 505 return decodeNeonUSThreeReg<VmaxD, VmaxQ>( 506 q, u, size, machInst, vd, vn, vm); 507 } 508 case 0x7: 509 if (b) { 510 return decodeNeonUSThreeReg<VabaD, VabaQ>( 511 q, u, size, machInst, vd, vn, vm); 512 } else { 513 if (bits(machInst, 23) == 1) { 514 if (q) { 515 return new Unknown(machInst); 516 } else { 517 return decodeNeonUSThreeUSReg<Vabdl>( 518 u, size, machInst, vd, vn, vm); 519 } 520 } else { 521 return decodeNeonUSThreeReg<VabdD, VabdQ>( 522 q, u, size, machInst, vd, vn, vm); 523 } 524 } 525 case 0x8: 526 if (b) { 527 if (u) { 528 return decodeNeonUThreeReg<VceqD, VceqQ>( 529 q, size, machInst, vd, vn, vm); 530 } else { 531 return decodeNeonUThreeReg<VtstD, VtstQ>( 532 q, size, machInst, vd, vn, vm); 533 } 534 } else { 535 if (u) { 536 return decodeNeonUThreeReg<NVsubD, NVsubQ>( 537 q, size, machInst, vd, vn, vm); 538 } else { 539 return decodeNeonUThreeReg<NVaddD, NVaddQ>( 540 q, size, machInst, vd, vn, vm); 541 } 542 } 543 case 0x9: 544 if (b) { 545 if (u) { 546 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 547 q, size, machInst, vd, vn, vm); 548 } else { 549 return decodeNeonSThreeReg<NVmulD, NVmulQ>( 550 q, size, machInst, vd, vn, vm); 551 } 552 } else { 553 if (u) { 554 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 555 q, u, size, machInst, vd, vn, vm); 556 } else { 557 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 558 q, u, size, machInst, vd, vn, vm); 559 } 560 } 561 case 0xa: 562 if (q) 563 return new Unknown(machInst); 564 if (b) { 565 return decodeNeonUSThreeUSReg<VpminD>( 566 u, size, machInst, vd, vn, vm); 567 } else { 568 return decodeNeonUSThreeUSReg<VpmaxD>( 569 u, size, machInst, vd, vn, vm); 570 } 571 case 0xb: 572 if (b) { 573 if (u || q) { 574 return new Unknown(machInst); 575 } else { 576 return decodeNeonUThreeUSReg<NVpaddD>( 577 size, machInst, vd, vn, vm); 578 } 579 } else { 580 if (u) { 581 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>( 582 q, size, machInst, vd, vn, vm); 583 } else { 584 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>( 585 q, size, machInst, vd, vn, vm); 586 } 587 } 588 case 0xc: 589 if (b) { 590 if (!u) { 591 if (bits(c, 1) == 0) { 592 if (q) { 593 return new NVfmaQFp<float>(machInst, vd, vn, vm); 594 } else { 595 return new NVfmaDFp<float>(machInst, vd, vn, vm); 596 } 597 } else { 598 if (q) { 599 return new NVfmsQFp<float>(machInst, vd, vn, vm); 600 } else { 601 return new NVfmsDFp<float>(machInst, vd, vn, vm); 602 } 603 } 604 } 605 } 606 return new Unknown(machInst); 607 case 0xd: 608 if (b) { 609 if (u) { 610 if (bits(c, 1) == 0) { 611 if (q) { 612 return new NVmulQFp<float>(machInst, vd, vn, vm); 613 } else { 614 return new NVmulDFp<float>(machInst, vd, vn, vm); 615 } 616 } else { 617 return new Unknown(machInst); 618 } 619 } else { 620 if (bits(c, 1) == 0) { 621 if (q) { 622 return new NVmlaQFp<float>(machInst, vd, vn, vm); 623 } else { 624 return new NVmlaDFp<float>(machInst, vd, vn, vm); 625 } 626 } else { 627 if (q) { 628 return new NVmlsQFp<float>(machInst, vd, vn, vm); 629 } else { 630 return new NVmlsDFp<float>(machInst, vd, vn, vm); 631 } 632 } 633 } 634 } else { 635 if (u) { 636 if (bits(c, 1) == 0) { 637 if (q) { 638 return new VpaddQFp<float>(machInst, vd, vn, vm); 639 } else { 640 return new VpaddDFp<float>(machInst, vd, vn, vm); 641 } 642 } else { 643 if (q) { 644 return new VabdQFp<float>(machInst, vd, vn, vm); 645 } else { 646 return new VabdDFp<float>(machInst, vd, vn, vm); 647 } 648 } 649 } else { 650 if (bits(c, 1) == 0) { 651 if (q) { 652 return new VaddQFp<float>(machInst, vd, vn, vm); 653 } else { 654 return new VaddDFp<float>(machInst, vd, vn, vm); 655 } 656 } else { 657 if (q) { 658 return new VsubQFp<float>(machInst, vd, vn, vm); 659 } else { 660 return new VsubDFp<float>(machInst, vd, vn, vm); 661 } 662 } 663 } 664 } 665 case 0xe: 666 if (b) { 667 if (u) { 668 if (bits(c, 1) == 0) { 669 if (q) { 670 return new VacgeQFp<float>(machInst, vd, vn, vm); 671 } else { 672 return new VacgeDFp<float>(machInst, vd, vn, vm); 673 } 674 } else { 675 if (q) { 676 return new VacgtQFp<float>(machInst, vd, vn, vm); 677 } else { 678 return new VacgtDFp<float>(machInst, vd, vn, vm); 679 } 680 } 681 } else { 682 return new Unknown(machInst); 683 } 684 } else { 685 if (u) { 686 if (bits(c, 1) == 0) { 687 if (q) { 688 return new VcgeQFp<float>(machInst, vd, vn, vm); 689 } else { 690 return new VcgeDFp<float>(machInst, vd, vn, vm); 691 } 692 } else { 693 if (q) { 694 return new VcgtQFp<float>(machInst, vd, vn, vm); 695 } else { 696 return new VcgtDFp<float>(machInst, vd, vn, vm); 697 } 698 } 699 } else { 700 if (bits(c, 1) == 0) { 701 if (q) { 702 return new VceqQFp<float>(machInst, vd, vn, vm); 703 } else { 704 return new VceqDFp<float>(machInst, vd, vn, vm); 705 } 706 } else { 707 return new Unknown(machInst); 708 } 709 } 710 } 711 case 0xf: 712 if (b) { 713 if (u) { 714 return new Unknown(machInst); 715 } else { 716 if (bits(c, 1) == 0) { 717 if (q) { 718 return new VrecpsQFp<float>(machInst, vd, vn, vm); 719 } else { 720 return new VrecpsDFp<float>(machInst, vd, vn, vm); 721 } 722 } else { 723 if (q) { 724 return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 725 } else { 726 return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 727 } 728 } 729 } 730 } else { 731 if (u) { 732 if (bits(c, 1) == 0) { 733 if (q) { 734 return new VpmaxQFp<float>(machInst, vd, vn, vm); 735 } else { 736 return new VpmaxDFp<float>(machInst, vd, vn, vm); 737 } 738 } else { 739 if (q) { 740 return new VpminQFp<float>(machInst, vd, vn, vm); 741 } else { 742 return new VpminDFp<float>(machInst, vd, vn, vm); 743 } 744 } 745 } else { 746 if (bits(c, 1) == 0) { 747 if (q) { 748 return new VmaxQFp<float>(machInst, vd, vn, vm); 749 } else { 750 return new VmaxDFp<float>(machInst, vd, vn, vm); 751 } 752 } else { 753 if (q) { 754 return new VminQFp<float>(machInst, vd, vn, vm); 755 } else { 756 return new VminDFp<float>(machInst, vd, vn, vm); 757 } 758 } 759 } 760 } 761 } 762 return new Unknown(machInst); 763 } 764 765 static StaticInstPtr 766 decodeNeonOneRegModImm(ExtMachInst machInst) 767 { 768 const IntRegIndex vd = 769 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 770 (bits(machInst, 22) << 4))); 771 const bool q = bits(machInst, 6); 772 const bool op = bits(machInst, 5); 773 const uint8_t cmode = bits(machInst, 11, 8); 774 const uint8_t imm = ((THUMB ? bits(machInst, 28) : 775 bits(machInst, 24)) << 7) | 776 (bits(machInst, 18, 16) << 4) | 777 (bits(machInst, 3, 0) << 0); 778 779 // Check for invalid immediate encodings and return an unknown op 780 // if it happens 781 bool immValid = true; 782 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid); 783 if (!immValid) { 784 return new Unknown(machInst); 785 } 786 787 if (op) { 788 if (bits(cmode, 3) == 0) { 789 if (bits(cmode, 0) == 0) { 790 if (q) 791 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 792 else 793 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 794 } else { 795 if (q) 796 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 797 else 798 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 799 } 800 } else { 801 if (bits(cmode, 2) == 1) { 802 switch (bits(cmode, 1, 0)) { 803 case 0: 804 case 1: 805 if (q) 806 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 807 else 808 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 809 case 2: 810 if (q) 811 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 812 else 813 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 814 case 3: 815 if (q) 816 return new Unknown(machInst); 817 else 818 return new Unknown(machInst); 819 } 820 } else { 821 if (bits(cmode, 0) == 0) { 822 if (q) 823 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 824 else 825 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 826 } else { 827 if (q) 828 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 829 else 830 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 831 } 832 } 833 } 834 } else { 835 if (bits(cmode, 3) == 0) { 836 if (bits(cmode, 0) == 0) { 837 if (q) 838 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 839 else 840 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 841 } else { 842 if (q) 843 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 844 else 845 return new NVorriD<uint64_t>(machInst, vd, bigImm); 846 } 847 } else { 848 if (bits(cmode, 2) == 1) { 849 if (q) 850 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 851 else 852 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 853 } else { 854 if (bits(cmode, 0) == 0) { 855 if (q) 856 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 857 else 858 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 859 } else { 860 if (q) 861 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 862 else 863 return new NVorriD<uint64_t>(machInst, vd, bigImm); 864 } 865 } 866 } 867 } 868 return new Unknown(machInst); 869 } 870 871 static StaticInstPtr 872 decodeNeonTwoRegAndShift(ExtMachInst machInst) 873 { 874 const uint32_t a = bits(machInst, 11, 8); 875 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 876 const bool b = bits(machInst, 6); 877 const bool l = bits(machInst, 7); 878 const IntRegIndex vd = 879 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 880 (bits(machInst, 22) << 4))); 881 const IntRegIndex vm = 882 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 883 (bits(machInst, 5) << 4))); 884 unsigned imm6 = bits(machInst, 21, 16); 885 unsigned imm = ((l ? 1 : 0) << 6) | imm6; 886 unsigned size = 3; 887 unsigned lShiftAmt = 0; 888 unsigned bitSel; 889 for (bitSel = 1 << 6; true; bitSel >>= 1) { 890 if (bitSel & imm) 891 break; 892 else if (!size) 893 return new Unknown(machInst); 894 size--; 895 } 896 lShiftAmt = imm6 & ~bitSel; 897 unsigned rShiftAmt = 0; 898 if (a != 0xe && a != 0xf) { 899 if (size > 2) 900 rShiftAmt = 64 - imm6; 901 else 902 rShiftAmt = 2 * (8 << size) - imm6; 903 } 904 905 switch (a) { 906 case 0x0: 907 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 908 b, u, size, machInst, vd, vm, rShiftAmt); 909 case 0x1: 910 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 911 b, u, size, machInst, vd, vm, rShiftAmt); 912 case 0x2: 913 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 914 b, u, size, machInst, vd, vm, rShiftAmt); 915 case 0x3: 916 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 917 b, u, size, machInst, vd, vm, rShiftAmt); 918 case 0x4: 919 if (u) { 920 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 921 b, size, machInst, vd, vm, rShiftAmt); 922 } else { 923 return new Unknown(machInst); 924 } 925 case 0x5: 926 if (u) { 927 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 928 b, size, machInst, vd, vm, lShiftAmt); 929 } else { 930 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 931 b, size, machInst, vd, vm, lShiftAmt); 932 } 933 case 0x6: 934 case 0x7: 935 if (u) { 936 if (a == 0x6) { 937 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 938 b, size, machInst, vd, vm, lShiftAmt); 939 } else { 940 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 941 b, size, machInst, vd, vm, lShiftAmt); 942 } 943 } else { 944 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 945 b, size, machInst, vd, vm, lShiftAmt); 946 } 947 case 0x8: 948 if (l) { 949 return new Unknown(machInst); 950 } else if (u) { 951 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 952 b, size, machInst, vd, vm, rShiftAmt); 953 } else { 954 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 955 b, size, machInst, vd, vm, rShiftAmt); 956 } 957 case 0x9: 958 if (l) { 959 return new Unknown(machInst); 960 } else if (u) { 961 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 962 b, size, machInst, vd, vm, rShiftAmt); 963 } else { 964 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 965 b, size, machInst, vd, vm, rShiftAmt); 966 } 967 case 0xa: 968 if (l || b) { 969 return new Unknown(machInst); 970 } else { 971 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 972 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); 973 } 974 case 0xe: 975 if (l) { 976 return new Unknown(machInst); 977 } else { 978 if (bits(imm6, 5) == 0) 979 return new Unknown(machInst); 980 if (u) { 981 if (b) { 982 return new NVcvtu2fpQ<float>( 983 machInst, vd, vm, 64 - imm6); 984 } else { 985 return new NVcvtu2fpD<float>( 986 machInst, vd, vm, 64 - imm6); 987 } 988 } else { 989 if (b) { 990 return new NVcvts2fpQ<float>( 991 machInst, vd, vm, 64 - imm6); 992 } else { 993 return new NVcvts2fpD<float>( 994 machInst, vd, vm, 64 - imm6); 995 } 996 } 997 } 998 case 0xf: 999 if (l) { 1000 return new Unknown(machInst); 1001 } else { 1002 if (bits(imm6, 5) == 0) 1003 return new Unknown(machInst); 1004 if (u) { 1005 if (b) { 1006 return new NVcvt2ufxQ<float>( 1007 machInst, vd, vm, 64 - imm6); 1008 } else { 1009 return new NVcvt2ufxD<float>( 1010 machInst, vd, vm, 64 - imm6); 1011 } 1012 } else { 1013 if (b) { 1014 return new NVcvt2sfxQ<float>( 1015 machInst, vd, vm, 64 - imm6); 1016 } else { 1017 return new NVcvt2sfxD<float>( 1018 machInst, vd, vm, 64 - imm6); 1019 } 1020 } 1021 } 1022 } 1023 return new Unknown(machInst); 1024 } 1025 1026 static StaticInstPtr 1027 decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 1028 { 1029 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1030 const uint32_t a = bits(machInst, 11, 8); 1031 const IntRegIndex vd = 1032 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1033 (bits(machInst, 22) << 4))); 1034 const IntRegIndex vn = 1035 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1036 (bits(machInst, 7) << 4))); 1037 const IntRegIndex vm = 1038 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1039 (bits(machInst, 5) << 4))); 1040 const unsigned size = bits(machInst, 21, 20); 1041 switch (a) { 1042 case 0x0: 1043 return decodeNeonUSThreeUSReg<Vaddl>( 1044 u, size, machInst, vd, vn, vm); 1045 case 0x1: 1046 return decodeNeonUSThreeUSReg<Vaddw>( 1047 u, size, machInst, vd, vn, vm); 1048 case 0x2: 1049 return decodeNeonUSThreeUSReg<Vsubl>( 1050 u, size, machInst, vd, vn, vm); 1051 case 0x3: 1052 return decodeNeonUSThreeUSReg<Vsubw>( 1053 u, size, machInst, vd, vn, vm); 1054 case 0x4: 1055 if (u) { 1056 return decodeNeonUThreeUSReg<Vraddhn>( 1057 size, machInst, vd, vn, vm); 1058 } else { 1059 return decodeNeonUThreeUSReg<Vaddhn>( 1060 size, machInst, vd, vn, vm); 1061 } 1062 case 0x5: 1063 return decodeNeonUSThreeUSReg<Vabal>( 1064 u, size, machInst, vd, vn, vm); 1065 case 0x6: 1066 if (u) { 1067 return decodeNeonUThreeUSReg<Vrsubhn>( 1068 size, machInst, vd, vn, vm); 1069 } else { 1070 return decodeNeonUThreeUSReg<Vsubhn>( 1071 size, machInst, vd, vn, vm); 1072 } 1073 case 0x7: 1074 if (bits(machInst, 23)) { 1075 return decodeNeonUSThreeUSReg<Vabdl>( 1076 u, size, machInst, vd, vn, vm); 1077 } else { 1078 return decodeNeonUSThreeReg<VabdD, VabdQ>( 1079 bits(machInst, 6), u, size, machInst, vd, vn, vm); 1080 } 1081 case 0x8: 1082 return decodeNeonUSThreeUSReg<Vmlal>( 1083 u, size, machInst, vd, vn, vm); 1084 case 0xa: 1085 return decodeNeonUSThreeUSReg<Vmlsl>( 1086 u, size, machInst, vd, vn, vm); 1087 case 0x9: 1088 if (u) { 1089 return new Unknown(machInst); 1090 } else { 1091 return decodeNeonSThreeUSReg<Vqdmlal>( 1092 size, machInst, vd, vn, vm); 1093 } 1094 case 0xb: 1095 if (u) { 1096 return new Unknown(machInst); 1097 } else { 1098 return decodeNeonSThreeUSReg<Vqdmlsl>( 1099 size, machInst, vd, vn, vm); 1100 } 1101 case 0xc: 1102 return decodeNeonUSThreeUSReg<Vmull>( 1103 u, size, machInst, vd, vn, vm); 1104 case 0xd: 1105 if (u) { 1106 return new Unknown(machInst); 1107 } else { 1108 return decodeNeonSThreeUSReg<Vqdmull>( 1109 size, machInst, vd, vn, vm); 1110 } 1111 case 0xe: 1112 return decodeNeonUThreeUSReg<Vmullp>( 1113 size, machInst, vd, vn, vm); 1114 } 1115 return new Unknown(machInst); 1116 } 1117 1118 static StaticInstPtr 1119 decodeNeonTwoRegScalar(ExtMachInst machInst) 1120 { 1121 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1122 const uint32_t a = bits(machInst, 11, 8); 1123 const unsigned size = bits(machInst, 21, 20); 1124 const IntRegIndex vd = 1125 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1126 (bits(machInst, 22) << 4))); 1127 const IntRegIndex vn = 1128 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1129 (bits(machInst, 7) << 4))); 1130 const IntRegIndex vm = (size == 2) ? 1131 (IntRegIndex)(2 * bits(machInst, 3, 0)) : 1132 (IntRegIndex)(2 * bits(machInst, 2, 0)); 1133 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 1134 (bits(machInst, 3) | (bits(machInst, 5) << 1)); 1135 switch (a) { 1136 case 0x0: 1137 if (u) { 1138 switch (size) { 1139 case 1: 1140 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 1141 case 2: 1142 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index); 1143 default: 1144 return new Unknown(machInst); 1145 } 1146 } else { 1147 switch (size) { 1148 case 1: 1149 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index); 1150 case 2: 1151 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 1152 default: 1153 return new Unknown(machInst); 1154 } 1155 } 1156 case 0x1: 1157 if (u) 1158 return new VmlasQFp<float>(machInst, vd, vn, vm, index); 1159 else 1160 return new VmlasDFp<float>(machInst, vd, vn, vm, index); 1161 case 0x4: 1162 if (u) { 1163 switch (size) { 1164 case 1: 1165 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 1166 case 2: 1167 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index); 1168 default: 1169 return new Unknown(machInst); 1170 } 1171 } else { 1172 switch (size) { 1173 case 1: 1174 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index); 1175 case 2: 1176 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 1177 default: 1178 return new Unknown(machInst); 1179 } 1180 } 1181 case 0x5: 1182 if (u) 1183 return new VmlssQFp<float>(machInst, vd, vn, vm, index); 1184 else 1185 return new VmlssDFp<float>(machInst, vd, vn, vm, index); 1186 case 0x2: 1187 if (u) { 1188 switch (size) { 1189 case 1: 1190 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 1191 case 2: 1192 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 1193 default: 1194 return new Unknown(machInst); 1195 } 1196 } else { 1197 switch (size) { 1198 case 1: 1199 return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 1200 case 2: 1201 return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 1202 default: 1203 return new Unknown(machInst); 1204 } 1205 } 1206 case 0x6: 1207 if (u) { 1208 switch (size) { 1209 case 1: 1210 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 1211 case 2: 1212 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 1213 default: 1214 return new Unknown(machInst); 1215 } 1216 } else { 1217 switch (size) { 1218 case 1: 1219 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 1220 case 2: 1221 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 1222 default: 1223 return new Unknown(machInst); 1224 } 1225 } 1226 case 0x3: 1227 if (u) { 1228 return new Unknown(machInst); 1229 } else { 1230 switch (size) { 1231 case 1: 1232 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 1233 case 2: 1234 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 1235 default: 1236 return new Unknown(machInst); 1237 } 1238 } 1239 case 0x7: 1240 if (u) { 1241 return new Unknown(machInst); 1242 } else { 1243 switch (size) { 1244 case 1: 1245 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 1246 case 2: 1247 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 1248 default: 1249 return new Unknown(machInst); 1250 } 1251 } 1252 case 0x8: 1253 if (u) { 1254 switch (size) { 1255 case 1: 1256 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 1257 case 2: 1258 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index); 1259 default: 1260 return new Unknown(machInst); 1261 } 1262 } else { 1263 switch (size) { 1264 case 1: 1265 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index); 1266 case 2: 1267 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 1268 default: 1269 return new Unknown(machInst); 1270 } 1271 } 1272 case 0x9: 1273 if (u) 1274 return new VmulsQFp<float>(machInst, vd, vn, vm, index); 1275 else 1276 return new VmulsDFp<float>(machInst, vd, vn, vm, index); 1277 case 0xa: 1278 if (u) { 1279 switch (size) { 1280 case 1: 1281 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 1282 case 2: 1283 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 1284 default: 1285 return new Unknown(machInst); 1286 } 1287 } else { 1288 switch (size) { 1289 case 1: 1290 return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 1291 case 2: 1292 return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 1293 default: 1294 return new Unknown(machInst); 1295 } 1296 } 1297 case 0xb: 1298 if (u) { 1299 return new Unknown(machInst); 1300 } else { 1301 if (u) { 1302 switch (size) { 1303 case 1: 1304 return new Vqdmulls<uint16_t>( 1305 machInst, vd, vn, vm, index); 1306 case 2: 1307 return new Vqdmulls<uint32_t>( 1308 machInst, vd, vn, vm, index); 1309 default: 1310 return new Unknown(machInst); 1311 } 1312 } else { 1313 switch (size) { 1314 case 1: 1315 return new Vqdmulls<int16_t>( 1316 machInst, vd, vn, vm, index); 1317 case 2: 1318 return new Vqdmulls<int32_t>( 1319 machInst, vd, vn, vm, index); 1320 default: 1321 return new Unknown(machInst); 1322 } 1323 } 1324 } 1325 case 0xc: 1326 if (u) { 1327 switch (size) { 1328 case 1: 1329 return new VqdmulhsQ<int16_t>( 1330 machInst, vd, vn, vm, index); 1331 case 2: 1332 return new VqdmulhsQ<int32_t>( 1333 machInst, vd, vn, vm, index); 1334 default: 1335 return new Unknown(machInst); 1336 } 1337 } else { 1338 switch (size) { 1339 case 1: 1340 return new VqdmulhsD<int16_t>( 1341 machInst, vd, vn, vm, index); 1342 case 2: 1343 return new VqdmulhsD<int32_t>( 1344 machInst, vd, vn, vm, index); 1345 default: 1346 return new Unknown(machInst); 1347 } 1348 } 1349 case 0xd: 1350 if (u) { 1351 switch (size) { 1352 case 1: 1353 return new VqrdmulhsQ<int16_t>( 1354 machInst, vd, vn, vm, index); 1355 case 2: 1356 return new VqrdmulhsQ<int32_t>( 1357 machInst, vd, vn, vm, index); 1358 default: 1359 return new Unknown(machInst); 1360 } 1361 } else { 1362 switch (size) { 1363 case 1: 1364 return new VqrdmulhsD<int16_t>( 1365 machInst, vd, vn, vm, index); 1366 case 2: 1367 return new VqrdmulhsD<int32_t>( 1368 machInst, vd, vn, vm, index); 1369 default: 1370 return new Unknown(machInst); 1371 } 1372 } 1373 } 1374 return new Unknown(machInst); 1375 } 1376 1377 static StaticInstPtr 1378 decodeNeonTwoRegMisc(ExtMachInst machInst) 1379 { 1380 const uint32_t a = bits(machInst, 17, 16); 1381 const uint32_t b = bits(machInst, 10, 6); 1382 const bool q = bits(machInst, 6); 1383 const IntRegIndex vd = 1384 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1385 (bits(machInst, 22) << 4))); 1386 const IntRegIndex vm = 1387 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1388 (bits(machInst, 5) << 4))); 1389 const unsigned size = bits(machInst, 19, 18); 1390 switch (a) { 1391 case 0x0: 1392 switch (bits(b, 4, 1)) { 1393 case 0x0: 1394 switch (size) { 1395 case 0: 1396 if (q) { 1397 return new NVrev64Q<uint8_t>(machInst, vd, vm); 1398 } else { 1399 return new NVrev64D<uint8_t>(machInst, vd, vm); 1400 } 1401 case 1: 1402 if (q) { 1403 return new NVrev64Q<uint16_t>(machInst, vd, vm); 1404 } else { 1405 return new NVrev64D<uint16_t>(machInst, vd, vm); 1406 } 1407 case 2: 1408 if (q) { 1409 return new NVrev64Q<uint32_t>(machInst, vd, vm); 1410 } else { 1411 return new NVrev64D<uint32_t>(machInst, vd, vm); 1412 } 1413 default: 1414 return new Unknown(machInst); 1415 } 1416 case 0x1: 1417 switch (size) { 1418 case 0: 1419 if (q) { 1420 return new NVrev32Q<uint8_t>(machInst, vd, vm); 1421 } else { 1422 return new NVrev32D<uint8_t>(machInst, vd, vm); 1423 } 1424 case 1: 1425 if (q) { 1426 return new NVrev32Q<uint16_t>(machInst, vd, vm); 1427 } else { 1428 return new NVrev32D<uint16_t>(machInst, vd, vm); 1429 } 1430 default: 1431 return new Unknown(machInst); 1432 } 1433 case 0x2: 1434 if (size != 0) { 1435 return new Unknown(machInst); 1436 } else if (q) { 1437 return new NVrev16Q<uint8_t>(machInst, vd, vm); 1438 } else { 1439 return new NVrev16D<uint8_t>(machInst, vd, vm); 1440 } 1441 case 0x4: 1442 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1443 q, size, machInst, vd, vm); 1444 case 0x5: 1445 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1446 q, size, machInst, vd, vm); 1447 case 0x8: 1448 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 1449 q, size, machInst, vd, vm); 1450 case 0x9: 1451 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 1452 q, size, machInst, vd, vm); 1453 case 0xa: 1454 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 1455 q, size, machInst, vd, vm); 1456 case 0xb: 1457 if (q) 1458 return new NVmvnQ<uint64_t>(machInst, vd, vm); 1459 else 1460 return new NVmvnD<uint64_t>(machInst, vd, vm); 1461 case 0xc: 1462 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 1463 q, size, machInst, vd, vm); 1464 case 0xd: 1465 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 1466 q, size, machInst, vd, vm); 1467 case 0xe: 1468 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 1469 q, size, machInst, vd, vm); 1470 case 0xf: 1471 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 1472 q, size, machInst, vd, vm); 1473 default: 1474 return new Unknown(machInst); 1475 } 1476 case 0x1: 1477 switch (bits(b, 3, 1)) { 1478 case 0x0: 1479 if (bits(b, 4)) { 1480 if (q) { 1481 return new NVcgtQFp<float>(machInst, vd, vm); 1482 } else { 1483 return new NVcgtDFp<float>(machInst, vd, vm); 1484 } 1485 } else { 1486 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 1487 q, size, machInst, vd, vm); 1488 } 1489 case 0x1: 1490 if (bits(b, 4)) { 1491 if (q) { 1492 return new NVcgeQFp<float>(machInst, vd, vm); 1493 } else { 1494 return new NVcgeDFp<float>(machInst, vd, vm); 1495 } 1496 } else { 1497 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 1498 q, size, machInst, vd, vm); 1499 } 1500 case 0x2: 1501 if (bits(b, 4)) { 1502 if (q) { 1503 return new NVceqQFp<float>(machInst, vd, vm); 1504 } else { 1505 return new NVceqDFp<float>(machInst, vd, vm); 1506 } 1507 } else { 1508 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 1509 q, size, machInst, vd, vm); 1510 } 1511 case 0x3: 1512 if (bits(b, 4)) { 1513 if (q) { 1514 return new NVcleQFp<float>(machInst, vd, vm); 1515 } else { 1516 return new NVcleDFp<float>(machInst, vd, vm); 1517 } 1518 } else { 1519 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 1520 q, size, machInst, vd, vm); 1521 } 1522 case 0x4: 1523 if (bits(b, 4)) { 1524 if (q) { 1525 return new NVcltQFp<float>(machInst, vd, vm); 1526 } else { 1527 return new NVcltDFp<float>(machInst, vd, vm); 1528 } 1529 } else { 1530 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 1531 q, size, machInst, vd, vm); 1532 } 1533 case 0x6: 1534 if (bits(machInst, 10)) { 1535 if (q) 1536 return new NVabsQFp<float>(machInst, vd, vm); 1537 else 1538 return new NVabsDFp<float>(machInst, vd, vm); 1539 } else { 1540 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 1541 q, size, machInst, vd, vm); 1542 } 1543 case 0x7: 1544 if (bits(machInst, 10)) { 1545 if (q) 1546 return new NVnegQFp<float>(machInst, vd, vm); 1547 else 1548 return new NVnegDFp<float>(machInst, vd, vm); 1549 } else { 1550 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 1551 q, size, machInst, vd, vm); 1552 } 1553 } 1554 case 0x2: 1555 switch (bits(b, 4, 1)) { 1556 case 0x0: 1557 if (q) 1558 return new NVswpQ<uint64_t>(machInst, vd, vm); 1559 else 1560 return new NVswpD<uint64_t>(machInst, vd, vm); 1561 case 0x1: 1562 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>( 1563 q, size, machInst, vd, vm); 1564 case 0x2: 1565 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 1566 q, size, machInst, vd, vm); 1567 case 0x3: 1568 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 1569 q, size, machInst, vd, vm); 1570 case 0x4: 1571 if (b == 0x8) { 1572 return decodeNeonUTwoMiscUSReg<NVmovn>( 1573 size, machInst, vd, vm); 1574 } else { 1575 return decodeNeonSTwoMiscUSReg<NVqmovuns>( 1576 size, machInst, vd, vm); 1577 } 1578 case 0x5: 1579 if (q) { 1580 return decodeNeonUTwoMiscUSReg<NVqmovun>( 1581 size, machInst, vd, vm); 1582 } else { 1583 return decodeNeonSTwoMiscUSReg<NVqmovn>( 1584 size, machInst, vd, vm); 1585 } 1586 case 0x6: 1587 if (b == 0xc) { 1588 return decodeNeonSTwoShiftUSReg<NVshll>( 1589 size, machInst, vd, vm, 8 << size); 1590 } else { 1591 return new Unknown(machInst); 1592 } 1593 case 0xc: 1594 case 0xe: 1595 if (b == 0x18) { 1596 if (size != 1 || (vm % 2)) 1597 return new Unknown(machInst); 1598 return new NVcvts2h<uint16_t>(machInst, vd, vm); 1599 } else if (b == 0x1c) { 1600 if (size != 1 || (vd % 2)) 1601 return new Unknown(machInst); 1602 return new NVcvth2s<uint16_t>(machInst, vd, vm); 1603 } else { 1604 return new Unknown(machInst); 1605 } 1606 default: 1607 return new Unknown(machInst); 1608 } 1609 case 0x3: 1610 if (bits(b, 4, 3) == 0x3) { 1611 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1612 return new Unknown(machInst); 1613 } else { 1614 if (bits(b, 2)) { 1615 if (bits(b, 1)) { 1616 if (q) { 1617 return new NVcvt2ufxQ<float>( 1618 machInst, vd, vm, 0); 1619 } else { 1620 return new NVcvt2ufxD<float>( 1621 machInst, vd, vm, 0); 1622 } 1623 } else { 1624 if (q) { 1625 return new NVcvt2sfxQ<float>( 1626 machInst, vd, vm, 0); 1627 } else { 1628 return new NVcvt2sfxD<float>( 1629 machInst, vd, vm, 0); 1630 } 1631 } 1632 } else { 1633 if (bits(b, 1)) { 1634 if (q) { 1635 return new NVcvtu2fpQ<float>( 1636 machInst, vd, vm, 0); 1637 } else { 1638 return new NVcvtu2fpD<float>( 1639 machInst, vd, vm, 0); 1640 } 1641 } else { 1642 if (q) { 1643 return new NVcvts2fpQ<float>( 1644 machInst, vd, vm, 0); 1645 } else { 1646 return new NVcvts2fpD<float>( 1647 machInst, vd, vm, 0); 1648 } 1649 } 1650 } 1651 } 1652 } else if ((b & 0x1a) == 0x10) { 1653 if (bits(b, 2)) { 1654 if (q) { 1655 return new NVrecpeQFp<float>(machInst, vd, vm); 1656 } else { 1657 return new NVrecpeDFp<float>(machInst, vd, vm); 1658 } 1659 } else { 1660 if (q) { 1661 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1662 } else { 1663 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1664 } 1665 } 1666 } else if ((b & 0x1a) == 0x12) { 1667 if (bits(b, 2)) { 1668 if (q) { 1669 return new NVrsqrteQFp<float>(machInst, vd, vm); 1670 } else { 1671 return new NVrsqrteDFp<float>(machInst, vd, vm); 1672 } 1673 } else { 1674 if (q) { 1675 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1676 } else { 1677 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1678 } 1679 } 1680 } else { 1681 return new Unknown(machInst); 1682 } 1683 } 1684 return new Unknown(machInst); 1685 } 1686 1687 StaticInstPtr 1688 decodeNeonData(ExtMachInst machInst) 1689 { 1690 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1691 const uint32_t a = bits(machInst, 23, 19); 1692 const uint32_t b = bits(machInst, 11, 8); 1693 const uint32_t c = bits(machInst, 7, 4); 1694 if (bits(a, 4) == 0) { 1695 return decodeNeonThreeRegistersSameLength(machInst); 1696 } else if ((c & 0x9) == 1) { 1697 if ((a & 0x7) == 0) { 1698 return decodeNeonOneRegModImm(machInst); 1699 } else { 1700 return decodeNeonTwoRegAndShift(machInst); 1701 } 1702 } else if ((c & 0x9) == 9) { 1703 return decodeNeonTwoRegAndShift(machInst); 1704 } else if (bits(a, 2, 1) != 0x3) { 1705 if ((c & 0x5) == 0) { 1706 return decodeNeonThreeRegDiffLengths(machInst); 1707 } else if ((c & 0x5) == 4) { 1708 return decodeNeonTwoRegScalar(machInst); 1709 } 1710 } else if ((a & 0x16) == 0x16) { 1711 const IntRegIndex vd = 1712 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1713 (bits(machInst, 22) << 4))); 1714 const IntRegIndex vn = 1715 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1716 (bits(machInst, 7) << 4))); 1717 const IntRegIndex vm = 1718 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1719 (bits(machInst, 5) << 4))); 1720 if (!u) { 1721 if (bits(c, 0) == 0) { 1722 unsigned imm4 = bits(machInst, 11, 8); 1723 bool q = bits(machInst, 6); 1724 if (imm4 >= 16 && !q) 1725 return new Unknown(machInst); 1726 if (q) { 1727 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1728 } else { 1729 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1730 } 1731 } 1732 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1733 return decodeNeonTwoRegMisc(machInst); 1734 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { 1735 unsigned length = bits(machInst, 9, 8) + 1; 1736 if ((uint32_t)vn / 2 + length > 32) 1737 return new Unknown(machInst); 1738 if (bits(machInst, 6) == 0) { 1739 switch (length) { 1740 case 1: 1741 return new NVtbl1(machInst, vd, vn, vm); 1742 case 2: 1743 return new NVtbl2(machInst, vd, vn, vm); 1744 case 3: 1745 return new NVtbl3(machInst, vd, vn, vm); 1746 case 4: 1747 return new NVtbl4(machInst, vd, vn, vm); 1748 } 1749 } else { 1750 switch (length) { 1751 case 1: 1752 return new NVtbx1(machInst, vd, vn, vm); 1753 case 2: 1754 return new NVtbx2(machInst, vd, vn, vm); 1755 case 3: 1756 return new NVtbx3(machInst, vd, vn, vm); 1757 case 4: 1758 return new NVtbx4(machInst, vd, vn, vm); 1759 } 1760 } 1761 } else if (b == 0xc && (c & 0x9) == 0) { 1762 unsigned imm4 = bits(machInst, 19, 16); 1763 if (bits(imm4, 2, 0) == 0) 1764 return new Unknown(machInst); 1765 unsigned size = 0; 1766 while ((imm4 & 0x1) == 0) { 1767 size++; 1768 imm4 >>= 1; 1769 } 1770 unsigned index = imm4 >> 1; 1771 const bool q = bits(machInst, 6); 1772 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1773 q, size, machInst, vd, vm, index); 1774 } 1775 } 1776 return new Unknown(machInst); 1777 } 1778 ''' 1779}}; 1780 1781def format ThumbNeonMem() {{ 1782 decode_block = ''' 1783 return decodeNeonMem(machInst); 1784 ''' 1785}}; 1786 1787def format ThumbNeonData() {{ 1788 decode_block = ''' 1789 return decodeNeonData(machInst); 1790 ''' 1791}}; 1792 1793let {{ 1794 header_output = ''' 1795 StaticInstPtr 1796 decodeExtensionRegLoadStore(ExtMachInst machInst); 1797 ''' 1798 decoder_output = ''' 1799 StaticInstPtr 1800 decodeExtensionRegLoadStore(ExtMachInst machInst) 1801 { 1802 const uint32_t opcode = bits(machInst, 24, 20); 1803 const uint32_t offset = bits(machInst, 7, 0); 1804 const bool single = (bits(machInst, 8) == 0); 1805 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1806 RegIndex vd; 1807 if (single) { 1808 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1809 bits(machInst, 22)); 1810 } else { 1811 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1812 (bits(machInst, 22) << 5)); 1813 } 1814 switch (bits(opcode, 4, 3)) { 1815 case 0x0: 1816 if (bits(opcode, 4, 1) == 0x2 && 1817 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1818 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1819 if ((bits(machInst, 7, 4) & 0xd) != 1) { 1820 break; 1821 } 1822 const IntRegIndex rt = 1823 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1824 const IntRegIndex rt2 = 1825 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1826 const bool op = bits(machInst, 20); 1827 uint32_t vm; 1828 if (single) { 1829 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1830 } else { 1831 vm = (bits(machInst, 3, 0) << 1) | 1832 (bits(machInst, 5) << 5); 1833 } 1834 if (op) { 1835 return new Vmov2Core2Reg(machInst, rt, rt2, 1836 (IntRegIndex)vm); 1837 } else { 1838 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1839 rt, rt2); 1840 } 1841 } 1842 break; 1843 case 0x1: 1844 { 1845 if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) { 1846 break; 1847 } 1848 switch (bits(opcode, 1, 0)) { 1849 case 0x0: 1850 return new VLdmStm(machInst, rn, vd, single, 1851 true, false, false, offset); 1852 case 0x1: 1853 return new VLdmStm(machInst, rn, vd, single, 1854 true, false, true, offset); 1855 case 0x2: 1856 return new VLdmStm(machInst, rn, vd, single, 1857 true, true, false, offset); 1858 case 0x3: 1859 // If rn == sp, then this is called vpop. 1860 return new VLdmStm(machInst, rn, vd, single, 1861 true, true, true, offset); 1862 } 1863 } 1864 case 0x2: 1865 if (bits(opcode, 1, 0) == 0x2) { 1866 // If rn == sp, then this is called vpush. 1867 return new VLdmStm(machInst, rn, vd, single, 1868 false, true, false, offset); 1869 } else if (bits(opcode, 1, 0) == 0x3) { 1870 return new VLdmStm(machInst, rn, vd, single, 1871 false, true, true, offset); 1872 } 1873 // Fall through on purpose 1874 case 0x3: 1875 const bool up = (bits(machInst, 23) == 1); 1876 const uint32_t imm = bits(machInst, 7, 0) << 2; 1877 if (single) { 1878 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1879 (bits(machInst, 22))); 1880 } else { 1881 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1882 (bits(machInst, 22) << 5)); 1883 } 1884 if (bits(opcode, 1, 0) == 0x0) { 1885 if (single) { 1886 if (up) { 1887 return new %(vstr_us)s(machInst, vd, rn, up, imm); 1888 } else { 1889 return new %(vstr_s)s(machInst, vd, rn, up, imm); 1890 } 1891 } else { 1892 if (up) { 1893 return new %(vstr_ud)s(machInst, vd, vd + 1, 1894 rn, up, imm); 1895 } else { 1896 return new %(vstr_d)s(machInst, vd, vd + 1, 1897 rn, up, imm); 1898 } 1899 } 1900 } else if (bits(opcode, 1, 0) == 0x1) { 1901 if (single) { 1902 if (up) { 1903 return new %(vldr_us)s(machInst, vd, rn, up, imm); 1904 } else { 1905 return new %(vldr_s)s(machInst, vd, rn, up, imm); 1906 } 1907 } else { 1908 if (up) { 1909 return new %(vldr_ud)s(machInst, vd, vd + 1, 1910 rn, up, imm); 1911 } else { 1912 return new %(vldr_d)s(machInst, vd, vd + 1, 1913 rn, up, imm); 1914 } 1915 } 1916 } 1917 } 1918 return new Unknown(machInst); 1919 } 1920 ''' % { 1921 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 1922 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 1923 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 1924 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 1925 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 1926 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 1927 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 1928 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 1929 } 1930}}; 1931 1932def format ExtensionRegLoadStore() {{ 1933 decode_block = ''' 1934 return decodeExtensionRegLoadStore(machInst); 1935 ''' 1936}}; 1937 1938let {{ 1939 header_output = ''' 1940 StaticInstPtr 1941 decodeShortFpTransfer(ExtMachInst machInst); 1942 ''' 1943 decoder_output = ''' 1944 StaticInstPtr 1945 decodeShortFpTransfer(ExtMachInst machInst) 1946 { 1947 const uint32_t l = bits(machInst, 20); 1948 const uint32_t c = bits(machInst, 8); 1949 const uint32_t a = bits(machInst, 23, 21); 1950 const uint32_t b = bits(machInst, 6, 5); 1951 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 1952 (machInst.thumb == 0 && machInst.condCode == 0xf)) { 1953 return new Unknown(machInst); 1954 } 1955 if (l == 0 && c == 0) { 1956 if (a == 0) { 1957 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 1958 bits(machInst, 7); 1959 const IntRegIndex rt = 1960 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1961 if (bits(machInst, 20) == 1) { 1962 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 1963 } else { 1964 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 1965 } 1966 } else if (a == 0x7) { 1967 const IntRegIndex rt = 1968 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1969 uint32_t reg = bits(machInst, 19, 16); 1970 uint32_t specReg; 1971 switch (reg) { 1972 case 0: 1973 specReg = MISCREG_FPSID; 1974 break; 1975 case 1: 1976 specReg = MISCREG_FPSCR; 1977 break; 1978 case 6: 1979 specReg = MISCREG_MVFR1; 1980 break; 1981 case 7: 1982 specReg = MISCREG_MVFR0; 1983 break; 1984 case 8: 1985 specReg = MISCREG_FPEXC; 1986 break; 1987 default: 1988 return new Unknown(machInst); 1989 } 1990 if (specReg == MISCREG_FPSCR) { 1991 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 1992 } else { 1993 uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt, 1994 reg, a, bits(machInst, 7, 5)); 1995 return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss); 1996 } 1997 } 1998 } else if (l == 0 && c == 1) { 1999 if (bits(a, 2) == 0) { 2000 uint32_t vd = (bits(machInst, 7) << 5) | 2001 (bits(machInst, 19, 16) << 1); 2002 // Handle accessing each single precision half of the vector. 2003 vd += bits(machInst, 21); 2004 const IntRegIndex rt = 2005 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2006 if (bits(machInst, 22) == 1) { 2007 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 2008 rt, bits(machInst, 6, 5)); 2009 } else if (bits(machInst, 5) == 1) { 2010 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 2011 rt, bits(machInst, 6)); 2012 } else if (bits(machInst, 6) == 0) { 2013 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 2014 } else { 2015 return new Unknown(machInst); 2016 } 2017 } else if (bits(b, 1) == 0) { 2018 bool q = bits(machInst, 21); 2019 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2020 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2021 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2022 IntRegIndex rt = (IntRegIndex)(uint32_t) 2023 bits(machInst, 15, 12); 2024 if (q) { 2025 switch (be) { 2026 case 0: 2027 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2028 case 1: 2029 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2030 case 2: 2031 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2032 case 3: 2033 return new Unknown(machInst); 2034 } 2035 } else { 2036 switch (be) { 2037 case 0: 2038 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2039 case 1: 2040 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2041 case 2: 2042 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2043 case 3: 2044 return new Unknown(machInst); 2045 } 2046 } 2047 } 2048 } else if (l == 1 && c == 0) { 2049 if (a == 0) { 2050 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2051 bits(machInst, 7); 2052 const IntRegIndex rt = 2053 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2054 if (bits(machInst, 20) == 1) { 2055 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2056 } else { 2057 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2058 } 2059 } else if (a == 7) { 2060 const IntRegIndex rt = 2061 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2062 uint32_t reg = bits(machInst, 19, 16); 2063 uint32_t specReg; 2064 switch (reg) { 2065 case 0: 2066 specReg = MISCREG_FPSID; 2067 break; 2068 case 1: 2069 specReg = MISCREG_FPSCR; 2070 break; 2071 case 6: 2072 specReg = MISCREG_MVFR1; 2073 break; 2074 case 7: 2075 specReg = MISCREG_MVFR0; 2076 break; 2077 case 8: 2078 specReg = MISCREG_FPEXC; 2079 break; 2080 default: 2081 return new Unknown(machInst); 2082 } 2083 if (rt == 0xf) { 2084 if (specReg == MISCREG_FPSCR) { 2085 return new VmrsApsrFpscr(machInst); 2086 } else { 2087 return new Unknown(machInst); 2088 } 2089 } else if (specReg == MISCREG_FPSCR) { 2090 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2091 } else { 2092 uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt, 2093 reg, a, bits(machInst, 7, 5)); 2094 return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss); 2095 } 2096 } 2097 } else { 2098 uint32_t vd = (bits(machInst, 7) << 5) | 2099 (bits(machInst, 19, 16) << 1); 2100 // Handle indexing into each single precision half of the vector. 2101 vd += bits(machInst, 21); 2102 uint32_t index; 2103 const IntRegIndex rt = 2104 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2105 const bool u = (bits(machInst, 23) == 1); 2106 if (bits(machInst, 22) == 1) { 2107 index = bits(machInst, 6, 5); 2108 if (u) { 2109 return new VmovRegCoreUB(machInst, rt, 2110 (IntRegIndex)vd, index); 2111 } else { 2112 return new VmovRegCoreSB(machInst, rt, 2113 (IntRegIndex)vd, index); 2114 } 2115 } else if (bits(machInst, 5) == 1) { 2116 index = bits(machInst, 6); 2117 if (u) { 2118 return new VmovRegCoreUH(machInst, rt, 2119 (IntRegIndex)vd, index); 2120 } else { 2121 return new VmovRegCoreSH(machInst, rt, 2122 (IntRegIndex)vd, index); 2123 } 2124 } else if (bits(machInst, 6) == 0 && !u) { 2125 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2126 } else { 2127 return new Unknown(machInst); 2128 } 2129 } 2130 return new Unknown(machInst); 2131 } 2132 ''' 2133}}; 2134 2135def format ShortFpTransfer() {{ 2136 decode_block = ''' 2137 return decodeShortFpTransfer(machInst); 2138 ''' 2139}}; 2140 2141let {{ 2142 header_output = ''' 2143 StaticInstPtr 2144 decodeVfpData(ExtMachInst machInst); 2145 ''' 2146 decoder_output = ''' 2147 StaticInstPtr 2148 decodeVfpData(ExtMachInst machInst) 2149 { 2150 const uint32_t opc1 = bits(machInst, 23, 20); 2151 const uint32_t opc2 = bits(machInst, 19, 16); 2152 const uint32_t opc3 = bits(machInst, 7, 6); 2153 //const uint32_t opc4 = bits(machInst, 3, 0); 2154 const bool single = (bits(machInst, 8) == 0); 2155 // Used to select between vcmp and vcmpe. 2156 const bool e = (bits(machInst, 7) == 1); 2157 IntRegIndex vd; 2158 IntRegIndex vm; 2159 IntRegIndex vn; 2160 if (single) { 2161 vd = (IntRegIndex)(bits(machInst, 22) | 2162 (bits(machInst, 15, 12) << 1)); 2163 vm = (IntRegIndex)(bits(machInst, 5) | 2164 (bits(machInst, 3, 0) << 1)); 2165 vn = (IntRegIndex)(bits(machInst, 7) | 2166 (bits(machInst, 19, 16) << 1)); 2167 } else { 2168 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2169 (bits(machInst, 15, 12) << 1)); 2170 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2171 (bits(machInst, 3, 0) << 1)); 2172 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2173 (bits(machInst, 19, 16) << 1)); 2174 } 2175 switch (opc1 & 0xb /* 1011 */) { 2176 case 0x0: 2177 if (bits(machInst, 6) == 0) { 2178 if (single) { 2179 return decodeVfpRegRegRegOp<VmlaS>( 2180 machInst, vd, vn, vm, false); 2181 } else { 2182 return decodeVfpRegRegRegOp<VmlaD>( 2183 machInst, vd, vn, vm, true); 2184 } 2185 } else { 2186 if (single) { 2187 return decodeVfpRegRegRegOp<VmlsS>( 2188 machInst, vd, vn, vm, false); 2189 } else { 2190 return decodeVfpRegRegRegOp<VmlsD>( 2191 machInst, vd, vn, vm, true); 2192 } 2193 } 2194 case 0x1: 2195 if (bits(machInst, 6) == 1) { 2196 if (single) { 2197 return decodeVfpRegRegRegOp<VnmlaS>( 2198 machInst, vd, vn, vm, false); 2199 } else { 2200 return decodeVfpRegRegRegOp<VnmlaD>( 2201 machInst, vd, vn, vm, true); 2202 } 2203 } else { 2204 if (single) { 2205 return decodeVfpRegRegRegOp<VnmlsS>( 2206 machInst, vd, vn, vm, false); 2207 } else { 2208 return decodeVfpRegRegRegOp<VnmlsD>( 2209 machInst, vd, vn, vm, true); 2210 } 2211 } 2212 case 0x2: 2213 if ((opc3 & 0x1) == 0) { 2214 if (single) { 2215 return decodeVfpRegRegRegOp<VmulS>( 2216 machInst, vd, vn, vm, false); 2217 } else { 2218 return decodeVfpRegRegRegOp<VmulD>( 2219 machInst, vd, vn, vm, true); 2220 } 2221 } else { 2222 if (single) { 2223 return decodeVfpRegRegRegOp<VnmulS>( 2224 machInst, vd, vn, vm, false); 2225 } else { 2226 return decodeVfpRegRegRegOp<VnmulD>( 2227 machInst, vd, vn, vm, true); 2228 } 2229 } 2230 case 0x3: 2231 if ((opc3 & 0x1) == 0) { 2232 if (single) { 2233 return decodeVfpRegRegRegOp<VaddS>( 2234 machInst, vd, vn, vm, false); 2235 } else { 2236 return decodeVfpRegRegRegOp<VaddD>( 2237 machInst, vd, vn, vm, true); 2238 } 2239 } else { 2240 if (single) { 2241 return decodeVfpRegRegRegOp<VsubS>( 2242 machInst, vd, vn, vm, false); 2243 } else { 2244 return decodeVfpRegRegRegOp<VsubD>( 2245 machInst, vd, vn, vm, true); 2246 } 2247 } 2248 case 0x8: 2249 if ((opc3 & 0x1) == 0) { 2250 if (single) { 2251 return decodeVfpRegRegRegOp<VdivS>( 2252 machInst, vd, vn, vm, false); 2253 } else { 2254 return decodeVfpRegRegRegOp<VdivD>( 2255 machInst, vd, vn, vm, true); 2256 } 2257 } 2258 break; 2259 case 0x9: 2260 if ((opc3 & 0x1) == 0) { 2261 if (single) { 2262 return decodeVfpRegRegRegOp<VfnmaS>( 2263 machInst, vd, vn, vm, false); 2264 } else { 2265 return decodeVfpRegRegRegOp<VfnmaD>( 2266 machInst, vd, vn, vm, true); 2267 } 2268 } else { 2269 if (single) { 2270 return decodeVfpRegRegRegOp<VfnmsS>( 2271 machInst, vd, vn, vm, false); 2272 } else { 2273 return decodeVfpRegRegRegOp<VfnmsD>( 2274 machInst, vd, vn, vm, true); 2275 } 2276 } 2277 break; 2278 case 0xa: 2279 if ((opc3 & 0x1) == 0) { 2280 if (single) { 2281 return decodeVfpRegRegRegOp<VfmaS>( 2282 machInst, vd, vn, vm, false); 2283 } else { 2284 return decodeVfpRegRegRegOp<VfmaD>( 2285 machInst, vd, vn, vm, true); 2286 } 2287 } else { 2288 if (single) { 2289 return decodeVfpRegRegRegOp<VfmsS>( 2290 machInst, vd, vn, vm, false); 2291 } else { 2292 return decodeVfpRegRegRegOp<VfmsD>( 2293 machInst, vd, vn, vm, true); 2294 } 2295 } 2296 break; 2297 case 0xb: 2298 if ((opc3 & 0x1) == 0) { 2299 const uint32_t baseImm = 2300 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2301 if (single) { 2302 uint32_t imm = vfp_modified_imm(baseImm, false); 2303 return decodeVfpRegImmOp<VmovImmS>( 2304 machInst, vd, imm, false); 2305 } else { 2306 uint64_t imm = vfp_modified_imm(baseImm, true); 2307 return decodeVfpRegImmOp<VmovImmD>( 2308 machInst, vd, imm, true); 2309 } 2310 } 2311 switch (opc2) { 2312 case 0x0: 2313 if (opc3 == 1) { 2314 if (single) { 2315 return decodeVfpRegRegOp<VmovRegS>( 2316 machInst, vd, vm, false); 2317 } else { 2318 return decodeVfpRegRegOp<VmovRegD>( 2319 machInst, vd, vm, true); 2320 } 2321 } else { 2322 if (single) { 2323 return decodeVfpRegRegOp<VabsS>( 2324 machInst, vd, vm, false); 2325 } else { 2326 return decodeVfpRegRegOp<VabsD>( 2327 machInst, vd, vm, true); 2328 } 2329 } 2330 case 0x1: 2331 if (opc3 == 1) { 2332 if (single) { 2333 return decodeVfpRegRegOp<VnegS>( 2334 machInst, vd, vm, false); 2335 } else { 2336 return decodeVfpRegRegOp<VnegD>( 2337 machInst, vd, vm, true); 2338 } 2339 } else { 2340 if (single) { 2341 return decodeVfpRegRegOp<VsqrtS>( 2342 machInst, vd, vm, false); 2343 } else { 2344 return decodeVfpRegRegOp<VsqrtD>( 2345 machInst, vd, vm, true); 2346 } 2347 } 2348 case 0x2: 2349 case 0x3: 2350 { 2351 const bool toHalf = bits(machInst, 16); 2352 const bool top = bits(machInst, 7); 2353 if (top) { 2354 if (toHalf) { 2355 return new VcvtFpSFpHT(machInst, vd, vm); 2356 } else { 2357 return new VcvtFpHTFpS(machInst, vd, vm); 2358 } 2359 } else { 2360 if (toHalf) { 2361 return new VcvtFpSFpHB(machInst, vd, vm); 2362 } else { 2363 return new VcvtFpHBFpS(machInst, vd, vm); 2364 } 2365 } 2366 } 2367 case 0x4: 2368 if (single) { 2369 if (e) { 2370 return new VcmpeS(machInst, vd, vm); 2371 } else { 2372 return new VcmpS(machInst, vd, vm); 2373 } 2374 } else { 2375 if (e) { 2376 return new VcmpeD(machInst, vd, vm); 2377 } else { 2378 return new VcmpD(machInst, vd, vm); 2379 } 2380 } 2381 case 0x5: 2382 if (single) { 2383 if (e) { 2384 return new VcmpeZeroS(machInst, vd, 0); 2385 } else { 2386 return new VcmpZeroS(machInst, vd, 0); 2387 } 2388 } else { 2389 if (e) { 2390 return new VcmpeZeroD(machInst, vd, 0); 2391 } else { 2392 return new VcmpZeroD(machInst, vd, 0); 2393 } 2394 } 2395 case 0x7: 2396 if (opc3 == 0x3) { 2397 if (single) { 2398 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2399 (bits(machInst, 15, 12) << 1)); 2400 return new VcvtFpSFpD(machInst, vd, vm); 2401 } else { 2402 vd = (IntRegIndex)(bits(machInst, 22) | 2403 (bits(machInst, 15, 12) << 1)); 2404 return new VcvtFpDFpS(machInst, vd, vm); 2405 } 2406 } 2407 break; 2408 case 0x8: 2409 if (bits(machInst, 7) == 0) { 2410 if (single) { 2411 return new VcvtUIntFpS(machInst, vd, vm); 2412 } else { 2413 vm = (IntRegIndex)(bits(machInst, 5) | 2414 (bits(machInst, 3, 0) << 1)); 2415 return new VcvtUIntFpD(machInst, vd, vm); 2416 } 2417 } else { 2418 if (single) { 2419 return new VcvtSIntFpS(machInst, vd, vm); 2420 } else { 2421 vm = (IntRegIndex)(bits(machInst, 5) | 2422 (bits(machInst, 3, 0) << 1)); 2423 return new VcvtSIntFpD(machInst, vd, vm); 2424 } 2425 } 2426 case 0xa: 2427 { 2428 const bool half = (bits(machInst, 7) == 0); 2429 const uint32_t imm = bits(machInst, 5) | 2430 (bits(machInst, 3, 0) << 1); 2431 const uint32_t size = 2432 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2433 if (single) { 2434 if (half) { 2435 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2436 } else { 2437 return new VcvtSFixedFpS(machInst, vd, vd, size); 2438 } 2439 } else { 2440 if (half) { 2441 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2442 } else { 2443 return new VcvtSFixedFpD(machInst, vd, vd, size); 2444 } 2445 } 2446 } 2447 case 0xb: 2448 { 2449 const bool half = (bits(machInst, 7) == 0); 2450 const uint32_t imm = bits(machInst, 5) | 2451 (bits(machInst, 3, 0) << 1); 2452 const uint32_t size = 2453 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2454 if (single) { 2455 if (half) { 2456 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2457 } else { 2458 return new VcvtUFixedFpS(machInst, vd, vd, size); 2459 } 2460 } else { 2461 if (half) { 2462 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2463 } else { 2464 return new VcvtUFixedFpD(machInst, vd, vd, size); 2465 } 2466 } 2467 } 2468 case 0xc: 2469 if (bits(machInst, 7) == 0) { 2470 if (single) { 2471 return new VcvtFpUIntSR(machInst, vd, vm); 2472 } else { 2473 vd = (IntRegIndex)(bits(machInst, 22) | 2474 (bits(machInst, 15, 12) << 1)); 2475 return new VcvtFpUIntDR(machInst, vd, vm); 2476 } 2477 } else { 2478 if (single) { 2479 return new VcvtFpUIntS(machInst, vd, vm); 2480 } else { 2481 vd = (IntRegIndex)(bits(machInst, 22) | 2482 (bits(machInst, 15, 12) << 1)); 2483 return new VcvtFpUIntD(machInst, vd, vm); 2484 } 2485 } 2486 case 0xd: 2487 if (bits(machInst, 7) == 0) { 2488 if (single) { 2489 return new VcvtFpSIntSR(machInst, vd, vm); 2490 } else { 2491 vd = (IntRegIndex)(bits(machInst, 22) | 2492 (bits(machInst, 15, 12) << 1)); 2493 return new VcvtFpSIntDR(machInst, vd, vm); 2494 } 2495 } else { 2496 if (single) { 2497 return new VcvtFpSIntS(machInst, vd, vm); 2498 } else { 2499 vd = (IntRegIndex)(bits(machInst, 22) | 2500 (bits(machInst, 15, 12) << 1)); 2501 return new VcvtFpSIntD(machInst, vd, vm); 2502 } 2503 } 2504 case 0xe: 2505 { 2506 const bool half = (bits(machInst, 7) == 0); 2507 const uint32_t imm = bits(machInst, 5) | 2508 (bits(machInst, 3, 0) << 1); 2509 const uint32_t size = 2510 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2511 if (single) { 2512 if (half) { 2513 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2514 } else { 2515 return new VcvtFpSFixedS(machInst, vd, vd, size); 2516 } 2517 } else { 2518 if (half) { 2519 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2520 } else { 2521 return new VcvtFpSFixedD(machInst, vd, vd, size); 2522 } 2523 } 2524 } 2525 case 0xf: 2526 { 2527 const bool half = (bits(machInst, 7) == 0); 2528 const uint32_t imm = bits(machInst, 5) | 2529 (bits(machInst, 3, 0) << 1); 2530 const uint32_t size = 2531 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2532 if (single) { 2533 if (half) { 2534 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2535 } else { 2536 return new VcvtFpUFixedS(machInst, vd, vd, size); 2537 } 2538 } else { 2539 if (half) { 2540 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2541 } else { 2542 return new VcvtFpUFixedD(machInst, vd, vd, size); 2543 } 2544 } 2545 } 2546 } 2547 break; 2548 } 2549 return new Unknown(machInst); 2550 } 2551 ''' 2552}}; 2553 2554def format VfpData() {{ 2555 decode_block = ''' 2556 return decodeVfpData(machInst); 2557 ''' 2558}}; 2559