fp.isa revision 11671:520509f3e66c
16657Snate@binkert.org// -*- mode:c++ -*- 26657Snate@binkert.org 310972Sdavid.hashe@amd.com// Copyright (c) 2010-2011,2016 ARM Limited 46657Snate@binkert.org// All rights reserved 56657Snate@binkert.org// 66657Snate@binkert.org// The license below extends only to copyright in the software and shall 76657Snate@binkert.org// not be construed as granting a license to any other intellectual 86657Snate@binkert.org// property including but not limited to intellectual property relating 96657Snate@binkert.org// to a hardware implementation of the functionality of the software 106657Snate@binkert.org// licensed hereunder. You may use the software subject to the license 116657Snate@binkert.org// terms below provided that you ensure that this notice is replicated 126657Snate@binkert.org// unmodified and in its entirety in all distributions of the software, 136657Snate@binkert.org// modified or unmodified, in source code or in binary form. 146657Snate@binkert.org// 156657Snate@binkert.org// Copyright (c) 2007-2008 The Florida State University 166657Snate@binkert.org// All rights reserved. 176657Snate@binkert.org// 186657Snate@binkert.org// Redistribution and use in source and binary forms, with or without 196657Snate@binkert.org// modification, are permitted provided that the following conditions are 206657Snate@binkert.org// met: redistributions of source code must retain the above copyright 216657Snate@binkert.org// notice, this list of conditions and the following disclaimer; 226657Snate@binkert.org// redistributions in binary form must reproduce the above copyright 236657Snate@binkert.org// notice, this list of conditions and the following disclaimer in the 246657Snate@binkert.org// documentation and/or other materials provided with the distribution; 256657Snate@binkert.org// neither the name of the copyright holders nor the names of its 266657Snate@binkert.org// contributors may be used to endorse or promote products derived from 276657Snate@binkert.org// this software without specific prior written permission. 286657Snate@binkert.org// 296999Snate@binkert.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 306657Snate@binkert.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316657Snate@binkert.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 326657Snate@binkert.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 336657Snate@binkert.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 348189SLisa.Hsu@amd.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 356657Snate@binkert.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 369499Snilay@cs.wisc.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 379499Snilay@cs.wisc.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 389364Snilay@cs.wisc.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 397055Snate@binkert.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 406882SBrad.Beckmann@amd.com// 416882SBrad.Beckmann@amd.com// Authors: Stephen Hines 428191SLisa.Hsu@amd.com 436882SBrad.Beckmann@amd.com//////////////////////////////////////////////////////////////////// 446882SBrad.Beckmann@amd.com// 459102SNuwan.Jayasena@amd.com// Floating Point operate instructions 4611084Snilay@cs.wisc.edu// 479366Snilay@cs.wisc.edu 489499Snilay@cs.wisc.eduoutput header {{ 499499Snilay@cs.wisc.edu 509499Snilay@cs.wisc.edu template<template <typename T> class Base> 516882SBrad.Beckmann@amd.com StaticInstPtr 526657Snate@binkert.org newNeonMemInst(const unsigned size, 536657Snate@binkert.org const ExtMachInst &machInst, 546657Snate@binkert.org const RegIndex dest, const RegIndex ra, 556657Snate@binkert.org const uint32_t imm, const unsigned extraMemFlags) 5610311Snilay@cs.wisc.edu { 5710311Snilay@cs.wisc.edu switch (size) { 5810311Snilay@cs.wisc.edu case 0: 5910311Snilay@cs.wisc.edu return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags); 606657Snate@binkert.org case 1: 6110311Snilay@cs.wisc.edu return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags); 629366Snilay@cs.wisc.edu case 2: 637839Snilay@cs.wisc.edu return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags); 646657Snate@binkert.org case 3: 656882SBrad.Beckmann@amd.com return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags); 6610308Snilay@cs.wisc.edu default: 6710308Snilay@cs.wisc.edu panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 686882SBrad.Beckmann@amd.com } 6910308Snilay@cs.wisc.edu } 7010308Snilay@cs.wisc.edu 7110308Snilay@cs.wisc.edu template<template <typename T> class Base> 7210308Snilay@cs.wisc.edu StaticInstPtr 7310308Snilay@cs.wisc.edu newNeonMixInst(const unsigned size, 749366Snilay@cs.wisc.edu const ExtMachInst &machInst, 759366Snilay@cs.wisc.edu const RegIndex dest, const RegIndex op1, 766657Snate@binkert.org const uint32_t step) 776657Snate@binkert.org { 786657Snate@binkert.org switch (size) { 796657Snate@binkert.org case 0: 809104Shestness@cs.utexas.edu return new Base<uint8_t>(machInst, dest, op1, step); 816657Snate@binkert.org case 1: 826657Snate@binkert.org return new Base<uint16_t>(machInst, dest, op1, step); 836657Snate@binkert.org case 2: 8410311Snilay@cs.wisc.edu return new Base<uint32_t>(machInst, dest, op1, step); 8510311Snilay@cs.wisc.edu case 3: 8610311Snilay@cs.wisc.edu return new Base<uint64_t>(machInst, dest, op1, step); 8710311Snilay@cs.wisc.edu default: 886657Snate@binkert.org panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 897839Snilay@cs.wisc.edu } 907839Snilay@cs.wisc.edu } 9110972Sdavid.hashe@amd.com 9210972Sdavid.hashe@amd.com}}; 9310972Sdavid.hashe@amd.com 946657Snate@binkert.orglet {{ 956657Snate@binkert.org header_output = ''' 966657Snate@binkert.org StaticInstPtr 976657Snate@binkert.org decodeNeonMem(ExtMachInst machInst); 986657Snate@binkert.org 996657Snate@binkert.org StaticInstPtr 1006657Snate@binkert.org decodeNeonData(ExtMachInst machInst); 1016657Snate@binkert.org ''' 1026657Snate@binkert.org 1036657Snate@binkert.org decoder_output = ''' 1046657Snate@binkert.org StaticInstPtr 1056657Snate@binkert.org decodeNeonMem(ExtMachInst machInst) 1066657Snate@binkert.org { 1076657Snate@binkert.org const uint32_t b = bits(machInst, 11, 8); 1086657Snate@binkert.org const bool single = bits(machInst, 23); 1096657Snate@binkert.org const bool singleAll = single && (bits(b, 3, 2) == 3); 1106657Snate@binkert.org const bool load = bits(machInst, 21); 1116657Snate@binkert.org 1126779SBrad.Beckmann@amd.com unsigned width = 0; 1136657Snate@binkert.org 1146657Snate@binkert.org if (single) { 1156657Snate@binkert.org width = bits(b, 1, 0) + 1; 1166657Snate@binkert.org } else { 1176657Snate@binkert.org switch (bits(b, 3, 1)) { 1186657Snate@binkert.org case 0x0: width = 4; 1196657Snate@binkert.org break; 1206657Snate@binkert.org case 0x1: width = (b & 0x1) ? 2 : 1; 1216657Snate@binkert.org break; 12210972Sdavid.hashe@amd.com case 0x2: width = 3; 12310972Sdavid.hashe@amd.com break; 12410972Sdavid.hashe@amd.com case 0x3: width = 1; 1259104Shestness@cs.utexas.edu break; 1269104Shestness@cs.utexas.edu case 0x4: width = 2; 1279104Shestness@cs.utexas.edu break; 1289104Shestness@cs.utexas.edu case 0x5: 1296657Snate@binkert.org if ((b & 0x1) == 0) { 1306657Snate@binkert.org width = 1; 1316657Snate@binkert.org break; 1326657Snate@binkert.org } 1336657Snate@binkert.org // Fall through on purpose. 1346657Snate@binkert.org default: 1356657Snate@binkert.org return new Unknown(machInst); 1366657Snate@binkert.org } 1376657Snate@binkert.org } 1386657Snate@binkert.org assert(width > 0 && width <= 4); 1396657Snate@binkert.org 1406657Snate@binkert.org const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0); 1416657Snate@binkert.org const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16); 14210307Snilay@cs.wisc.edu const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) | 1436657Snate@binkert.org bits(machInst, 22) << 4); 1446657Snate@binkert.org const uint32_t type = bits(machInst, 11, 8); 1457839Snilay@cs.wisc.edu uint32_t size = 0; 1467839Snilay@cs.wisc.edu uint32_t align = TLB::MustBeOne; 1477839Snilay@cs.wisc.edu unsigned inc = 1; 1487839Snilay@cs.wisc.edu unsigned regs = 1; 1497839Snilay@cs.wisc.edu unsigned lane = 0; 1507839Snilay@cs.wisc.edu if (single) { 1517839Snilay@cs.wisc.edu if (singleAll) { 1527839Snilay@cs.wisc.edu size = bits(machInst, 7, 6); 1537839Snilay@cs.wisc.edu bool t = bits(machInst, 5); 1547839Snilay@cs.wisc.edu align = size | TLB::AllowUnaligned; 15510968Sdavid.hashe@amd.com if (width == 1) { 15610968Sdavid.hashe@amd.com regs = t ? 2 : 1; 15710968Sdavid.hashe@amd.com inc = 1; 15810968Sdavid.hashe@amd.com } else { 15910968Sdavid.hashe@amd.com regs = width; 16010968Sdavid.hashe@amd.com inc = t ? 2 : 1; 16110968Sdavid.hashe@amd.com } 1627839Snilay@cs.wisc.edu switch (width) { 1636657Snate@binkert.org case 1: 1646657Snate@binkert.org case 2: 1656657Snate@binkert.org if (bits(machInst, 4)) 1666657Snate@binkert.org align = size + width - 1; 1676657Snate@binkert.org break; 1686657Snate@binkert.org case 3: 1696657Snate@binkert.org break; 1706657Snate@binkert.org case 4: 1716657Snate@binkert.org if (size == 3) { 1726657Snate@binkert.org if (bits(machInst, 4) == 0) 1736657Snate@binkert.org return new Unknown(machInst); 1746657Snate@binkert.org size = 2; 1756657Snate@binkert.org align = 0x4; 1766657Snate@binkert.org } else if (size == 2) { 1776657Snate@binkert.org if (bits(machInst, 4)) 1786657Snate@binkert.org align = 0x3; 1796657Snate@binkert.org } else { 1806657Snate@binkert.org if (bits(machInst, 4)) 1816657Snate@binkert.org align = size + 2; 1826657Snate@binkert.org } 1836657Snate@binkert.org break; 1846657Snate@binkert.org } 1856657Snate@binkert.org } else { 1866657Snate@binkert.org size = bits(machInst, 11, 10); 1876657Snate@binkert.org align = size | TLB::AllowUnaligned; 1886657Snate@binkert.org regs = width; 1896657Snate@binkert.org unsigned indexAlign = bits(machInst, 7, 4); 1906657Snate@binkert.org // If width is 1, inc is always 1. That's overridden later. 1916657Snate@binkert.org switch (size) { 1926657Snate@binkert.org case 0: 19310963Sdavid.hashe@amd.com inc = 1; 19410963Sdavid.hashe@amd.com lane = bits(indexAlign, 3, 1); 19510963Sdavid.hashe@amd.com break; 19610963Sdavid.hashe@amd.com case 1: 19710963Sdavid.hashe@amd.com inc = bits(indexAlign, 1) ? 2 : 1; 19810963Sdavid.hashe@amd.com lane = bits(indexAlign, 3, 2); 19911095Snilay@cs.wisc.edu break; 20010963Sdavid.hashe@amd.com case 2: 20110963Sdavid.hashe@amd.com inc = bits(indexAlign, 2) ? 2 : 1; 20210963Sdavid.hashe@amd.com lane = bits(indexAlign, 3); 20310963Sdavid.hashe@amd.com break; 20410963Sdavid.hashe@amd.com } 20510963Sdavid.hashe@amd.com // Override inc for width of 1. 20610963Sdavid.hashe@amd.com if (width == 1) { 20710963Sdavid.hashe@amd.com inc = 1; 2089219Spower.jg@gmail.com } 2096877Ssteve.reinhardt@amd.com switch (width) { 2106657Snate@binkert.org case 1: 2119219Spower.jg@gmail.com switch (size) { 2126657Snate@binkert.org case 0: 2139219Spower.jg@gmail.com break; 2146657Snate@binkert.org case 1: 2156877Ssteve.reinhardt@amd.com if (bits(indexAlign, 0)) 2166999Snate@binkert.org align = 1; 2176877Ssteve.reinhardt@amd.com break; 21810308Snilay@cs.wisc.edu case 2: 2196877Ssteve.reinhardt@amd.com if (bits(indexAlign, 1, 0)) 2206877Ssteve.reinhardt@amd.com align = 2; 22110308Snilay@cs.wisc.edu break; 2226877Ssteve.reinhardt@amd.com } 2236877Ssteve.reinhardt@amd.com break; 2246877Ssteve.reinhardt@amd.com case 2: 2256877Ssteve.reinhardt@amd.com if (bits(indexAlign, 0)) 2266877Ssteve.reinhardt@amd.com align = size + 1; 2276877Ssteve.reinhardt@amd.com break; 2286877Ssteve.reinhardt@amd.com case 3: 2299338SAndreas.Sandberg@arm.com break; 2306877Ssteve.reinhardt@amd.com case 4: 2316877Ssteve.reinhardt@amd.com switch (size) { 2326877Ssteve.reinhardt@amd.com case 0: 2336877Ssteve.reinhardt@amd.com case 1: 23410308Snilay@cs.wisc.edu if (bits(indexAlign, 0)) 23510308Snilay@cs.wisc.edu align = size + 2; 23610308Snilay@cs.wisc.edu break; 23710308Snilay@cs.wisc.edu case 2: 23811084Snilay@cs.wisc.edu if (bits(indexAlign, 0)) 2396882SBrad.Beckmann@amd.com align = bits(indexAlign, 1, 0) + 2; 24010308Snilay@cs.wisc.edu break; 24110308Snilay@cs.wisc.edu } 2426882SBrad.Beckmann@amd.com break; 2436882SBrad.Beckmann@amd.com } 2446882SBrad.Beckmann@amd.com } 2456882SBrad.Beckmann@amd.com if (size == 0x3) { 24611021Sjthestness@gmail.com return new Unknown(machInst); 2476877Ssteve.reinhardt@amd.com } 2486877Ssteve.reinhardt@amd.com } else { 24910917Sbrandon.potter@amd.com size = bits(machInst, 7, 6); 2506877Ssteve.reinhardt@amd.com align = bits(machInst, 5, 4); 2516657Snate@binkert.org if (align == 0) { 2526657Snate@binkert.org // @align wasn't specified, so alignment can be turned off. 2536999Snate@binkert.org align = size | TLB::AllowUnaligned; 2546657Snate@binkert.org } else { 2556657Snate@binkert.org align = align + 2; 2566657Snate@binkert.org } 2576657Snate@binkert.org switch (width) { 2587007Snate@binkert.org case 1: 2596657Snate@binkert.org switch (type) { 2606657Snate@binkert.org case 0x7: regs = 1; 2616657Snate@binkert.org break; 2626657Snate@binkert.org case 0xa: regs = 2; 2636657Snate@binkert.org break; 2647007Snate@binkert.org case 0x6: regs = 3; 2657007Snate@binkert.org break; 2666657Snate@binkert.org case 0x2: regs = 4; 2677002Snate@binkert.org break; 2687002Snate@binkert.org default: 2697002Snate@binkert.org return new Unknown(machInst); 2707002Snate@binkert.org } 2716657Snate@binkert.org break; 2726657Snate@binkert.org case 2: 2738229Snate@binkert.org // Regs doesn't behave exactly as it does in the manual 2748229Snate@binkert.org // because they loop over regs registers twice and we break 2758229Snate@binkert.org // it down in the macroop. 27610972Sdavid.hashe@amd.com switch (type) { 2776657Snate@binkert.org case 0x8: regs = 2; inc = 1; 2786657Snate@binkert.org break; 2796657Snate@binkert.org case 0x9: regs = 2; inc = 2; 2806657Snate@binkert.org break; 2816793SBrad.Beckmann@amd.com case 0x3: regs = 4; inc = 2; 2826657Snate@binkert.org break; 28310311Snilay@cs.wisc.edu default: 2846657Snate@binkert.org return new Unknown(machInst); 2856657Snate@binkert.org } 2866657Snate@binkert.org break; 2877002Snate@binkert.org case 3: 2886657Snate@binkert.org regs = 3; 2897007Snate@binkert.org switch (type) { 2907007Snate@binkert.org case 0x4: inc = 1; 2919271Snilay@cs.wisc.edu break; 2926877Ssteve.reinhardt@amd.com case 0x5: inc = 2;; 2936877Ssteve.reinhardt@amd.com break; 2946657Snate@binkert.org default: 2956877Ssteve.reinhardt@amd.com return new Unknown(machInst); 29610311Snilay@cs.wisc.edu } 29711084Snilay@cs.wisc.edu break; 29811084Snilay@cs.wisc.edu case 4: 29911021Sjthestness@gmail.com regs = 4; 3009745Snilay@cs.wisc.edu switch (type) { 3017002Snate@binkert.org case 0: inc = 1; 3026657Snate@binkert.org break; 30310012Snilay@cs.wisc.edu case 1: inc = 2; 3049745Snilay@cs.wisc.edu break; 3059745Snilay@cs.wisc.edu default: 3069745Snilay@cs.wisc.edu return new Unknown(machInst); 3078683Snilay@cs.wisc.edu } 3088683Snilay@cs.wisc.edu break; 3097007Snate@binkert.org } 31010524Snilay@cs.wisc.edu } 3119302Snilay@cs.wisc.edu 3129745Snilay@cs.wisc.edu if (load) { 3139745Snilay@cs.wisc.edu // Load instructions. 31411061Snilay@cs.wisc.edu if (single) { 3159745Snilay@cs.wisc.edu return new VldSingle(machInst, singleAll, width, rn, vd, 31611061Snilay@cs.wisc.edu regs, inc, size, align, rm, lane); 3179745Snilay@cs.wisc.edu } else { 3186657Snate@binkert.org return new VldMult(machInst, width, rn, vd, 3196657Snate@binkert.org regs, inc, size, align, rm); 3206657Snate@binkert.org } 3216657Snate@binkert.org } else { 3226657Snate@binkert.org // Store instructions. 3236657Snate@binkert.org if (single) { 3246882SBrad.Beckmann@amd.com if (singleAll) { 3256882SBrad.Beckmann@amd.com return new Unknown(machInst); 3266882SBrad.Beckmann@amd.com } else { 3276882SBrad.Beckmann@amd.com return new VstSingle(machInst, false, width, rn, vd, 3286657Snate@binkert.org regs, inc, size, align, rm, lane); 3296657Snate@binkert.org } 3307007Snate@binkert.org } else { 3317839Snilay@cs.wisc.edu return new VstMult(machInst, width, rn, vd, 3327839Snilay@cs.wisc.edu regs, inc, size, align, rm); 3337839Snilay@cs.wisc.edu } 3347839Snilay@cs.wisc.edu } 3357839Snilay@cs.wisc.edu return new Unknown(machInst); 3367839Snilay@cs.wisc.edu } 3377839Snilay@cs.wisc.edu ''' 3387839Snilay@cs.wisc.edu 3397839Snilay@cs.wisc.edu decoder_output += ''' 3407839Snilay@cs.wisc.edu static StaticInstPtr 3417839Snilay@cs.wisc.edu decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 3427839Snilay@cs.wisc.edu { 34311025Snilay@cs.wisc.edu const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 3447007Snate@binkert.org const uint32_t a = bits(machInst, 11, 8); 3457007Snate@binkert.org const bool b = bits(machInst, 4); 3467007Snate@binkert.org const uint32_t c = bits(machInst, 21, 20); 3477007Snate@binkert.org const IntRegIndex vd = 3487839Snilay@cs.wisc.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 3497839Snilay@cs.wisc.edu (bits(machInst, 22) << 4))); 3507839Snilay@cs.wisc.edu const IntRegIndex vn = 3517839Snilay@cs.wisc.edu (IntRegIndex)(2 * (bits(machInst, 19, 16) | 3527839Snilay@cs.wisc.edu (bits(machInst, 7) << 4))); 3537839Snilay@cs.wisc.edu const IntRegIndex vm = 3547839Snilay@cs.wisc.edu (IntRegIndex)(2 * (bits(machInst, 3, 0) | 3557839Snilay@cs.wisc.edu (bits(machInst, 5) << 4))); 3567839Snilay@cs.wisc.edu const unsigned size = bits(machInst, 21, 20); 3577839Snilay@cs.wisc.edu const bool q = bits(machInst, 6); 3587839Snilay@cs.wisc.edu if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1))) 3597839Snilay@cs.wisc.edu return new Unknown(machInst); 36011025Snilay@cs.wisc.edu switch (a) { 3617007Snate@binkert.org case 0x0: 3629745Snilay@cs.wisc.edu if (b) { 3639745Snilay@cs.wisc.edu if (u) { 3649745Snilay@cs.wisc.edu return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 3659745Snilay@cs.wisc.edu q, size, machInst, vd, vn, vm); 3669745Snilay@cs.wisc.edu } else { 3679745Snilay@cs.wisc.edu return decodeNeonSThreeReg<VqaddSD, VqaddSQ>( 3686657Snate@binkert.org q, size, machInst, vd, vn, vm); 3697007Snate@binkert.org } 3706657Snate@binkert.org } else { 3716657Snate@binkert.org if (size == 3) 3726657Snate@binkert.org return new Unknown(machInst); 3736657Snate@binkert.org return decodeNeonUSThreeReg<VhaddD, VhaddQ>( 3746657Snate@binkert.org q, u, size, machInst, vd, vn, vm); 3756657Snate@binkert.org } 3766657Snate@binkert.org case 0x1: 3776657Snate@binkert.org if (!b) { 3787839Snilay@cs.wisc.edu return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>( 3797839Snilay@cs.wisc.edu q, u, size, machInst, vd, vn, vm); 3807839Snilay@cs.wisc.edu } else { 3817839Snilay@cs.wisc.edu if (u) { 3827839Snilay@cs.wisc.edu switch (c) { 3837839Snilay@cs.wisc.edu case 0: 3847839Snilay@cs.wisc.edu if (q) { 3857839Snilay@cs.wisc.edu return new VeorQ<uint64_t>(machInst, vd, vn, vm); 3867839Snilay@cs.wisc.edu } else { 3877839Snilay@cs.wisc.edu return new VeorD<uint64_t>(machInst, vd, vn, vm); 3887839Snilay@cs.wisc.edu } 3897839Snilay@cs.wisc.edu case 1: 3907839Snilay@cs.wisc.edu if (q) { 3917839Snilay@cs.wisc.edu return new VbslQ<uint64_t>(machInst, vd, vn, vm); 3927839Snilay@cs.wisc.edu } else { 3937839Snilay@cs.wisc.edu return new VbslD<uint64_t>(machInst, vd, vn, vm); 39410121Snilay@cs.wisc.edu } 3956657Snate@binkert.org case 2: 3966657Snate@binkert.org if (q) { 3976657Snate@binkert.org return new VbitQ<uint64_t>(machInst, vd, vn, vm); 3986657Snate@binkert.org } else { 3997839Snilay@cs.wisc.edu return new VbitD<uint64_t>(machInst, vd, vn, vm); 4007839Snilay@cs.wisc.edu } 4017839Snilay@cs.wisc.edu case 3: 40210121Snilay@cs.wisc.edu if (q) { 40310121Snilay@cs.wisc.edu return new VbifQ<uint64_t>(machInst, vd, vn, vm); 40411025Snilay@cs.wisc.edu } else { 4057839Snilay@cs.wisc.edu return new VbifD<uint64_t>(machInst, vd, vn, vm); 4067839Snilay@cs.wisc.edu } 4077839Snilay@cs.wisc.edu } 40810121Snilay@cs.wisc.edu } else { 40911025Snilay@cs.wisc.edu switch (c) { 4107839Snilay@cs.wisc.edu case 0: 4117839Snilay@cs.wisc.edu if (q) { 4127839Snilay@cs.wisc.edu return new VandQ<uint64_t>(machInst, vd, vn, vm); 41310121Snilay@cs.wisc.edu } else { 41411025Snilay@cs.wisc.edu return new VandD<uint64_t>(machInst, vd, vn, vm); 4157839Snilay@cs.wisc.edu } 4167839Snilay@cs.wisc.edu case 1: 4177839Snilay@cs.wisc.edu if (q) { 41811025Snilay@cs.wisc.edu return new VbicQ<uint64_t>(machInst, vd, vn, vm); 4196657Snate@binkert.org } else { 4206657Snate@binkert.org return new VbicD<uint64_t>(machInst, vd, vn, vm); 4216657Snate@binkert.org } 4226657Snate@binkert.org case 2: 4237007Snate@binkert.org if (vn == vm) { 4246657Snate@binkert.org if (q) { 4256657Snate@binkert.org return new VmovQ<uint64_t>( 4269273Snilay@cs.wisc.edu machInst, vd, vn, vm); 42710305Snilay@cs.wisc.edu } else { 4286657Snate@binkert.org return new VmovD<uint64_t>( 4296657Snate@binkert.org machInst, vd, vn, vm); 4306657Snate@binkert.org } 4317007Snate@binkert.org } else { 4326657Snate@binkert.org if (q) { 4336657Snate@binkert.org return new VorrQ<uint64_t>( 4349219Spower.jg@gmail.com machInst, vd, vn, vm); 4356657Snate@binkert.org } else { 4366657Snate@binkert.org return new VorrD<uint64_t>( 4376999Snate@binkert.org machInst, vd, vn, vm); 4386657Snate@binkert.org } 4396657Snate@binkert.org } 4406657Snate@binkert.org case 3: 4416657Snate@binkert.org if (q) { 4427007Snate@binkert.org return new VornQ<uint64_t>( 4436657Snate@binkert.org machInst, vd, vn, vm); 4446657Snate@binkert.org } else { 4456657Snate@binkert.org return new VornD<uint64_t>( 4466657Snate@binkert.org machInst, vd, vn, vm); 4476657Snate@binkert.org } 4488946Sandreas.hansson@arm.com } 4498946Sandreas.hansson@arm.com } 4508946Sandreas.hansson@arm.com } 4517832Snate@binkert.org case 0x2: 4527002Snate@binkert.org if (b) { 4537002Snate@binkert.org if (u) { 45410972Sdavid.hashe@amd.com return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 4557002Snate@binkert.org q, size, machInst, vd, vn, vm); 4568641Snate@binkert.org } else { 4577056Snate@binkert.org return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 45810972Sdavid.hashe@amd.com q, size, machInst, vd, vn, vm); 45910972Sdavid.hashe@amd.com } 46010972Sdavid.hashe@amd.com } else { 46110972Sdavid.hashe@amd.com if (size == 3) 46210972Sdavid.hashe@amd.com return new Unknown(machInst); 4636657Snate@binkert.org return decodeNeonUSThreeReg<VhsubD, VhsubQ>( 4648229Snate@binkert.org q, u, size, machInst, vd, vn, vm); 4656657Snate@binkert.org } 4666657Snate@binkert.org case 0x3: 46711108Sdavid.hashe@amd.com if (b) { 46810972Sdavid.hashe@amd.com return decodeNeonUSThreeReg<VcgeD, VcgeQ>( 4699219Spower.jg@gmail.com q, u, size, machInst, vd, vn, vm); 4709219Spower.jg@gmail.com } else { 4719219Spower.jg@gmail.com return decodeNeonUSThreeReg<VcgtD, VcgtQ>( 4729219Spower.jg@gmail.com q, u, size, machInst, vd, vn, vm); 4739219Spower.jg@gmail.com } 4747002Snate@binkert.org case 0x4: 4757002Snate@binkert.org if (b) { 4766657Snate@binkert.org if (u) { 4776657Snate@binkert.org return decodeNeonUThreeReg<VqshlUD, VqshlUQ>( 4786657Snate@binkert.org q, size, machInst, vd, vm, vn); 4796657Snate@binkert.org } else { 4806657Snate@binkert.org return decodeNeonSThreeReg<VqshlSD, VqshlSQ>( 4816793SBrad.Beckmann@amd.com q, size, machInst, vd, vm, vn); 4826657Snate@binkert.org } 4836657Snate@binkert.org } else { 4846657Snate@binkert.org return decodeNeonUSThreeReg<VshlD, VshlQ>( 48510121Snilay@cs.wisc.edu q, u, size, machInst, vd, vm, vn); 48610121Snilay@cs.wisc.edu } 4876657Snate@binkert.org case 0x5: 4886877Ssteve.reinhardt@amd.com if (b) { 4896877Ssteve.reinhardt@amd.com if (u) { 4906877Ssteve.reinhardt@amd.com return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>( 4916877Ssteve.reinhardt@amd.com q, size, machInst, vd, vm, vn); 4926877Ssteve.reinhardt@amd.com } else { 4936877Ssteve.reinhardt@amd.com return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>( 4946657Snate@binkert.org q, size, machInst, vd, vm, vn); 4959745Snilay@cs.wisc.edu } 4969745Snilay@cs.wisc.edu } else { 4976657Snate@binkert.org return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 4987007Snate@binkert.org q, u, size, machInst, vd, vm, vn); 4996657Snate@binkert.org } 5009801Snilay@cs.wisc.edu case 0x6: 5019801Snilay@cs.wisc.edu if (b) { 5026657Snate@binkert.org return decodeNeonUSThreeReg<VminD, VminQ>( 5039801Snilay@cs.wisc.edu q, u, size, machInst, vd, vn, vm); 5049801Snilay@cs.wisc.edu } else { 5059801Snilay@cs.wisc.edu return decodeNeonUSThreeReg<VmaxD, VmaxQ>( 5067007Snate@binkert.org q, u, size, machInst, vd, vn, vm); 5076657Snate@binkert.org } 5086877Ssteve.reinhardt@amd.com case 0x7: 5096877Ssteve.reinhardt@amd.com if (b) { 5106657Snate@binkert.org return decodeNeonUSThreeReg<VabaD, VabaQ>( 51110078Snilay@cs.wisc.edu q, u, size, machInst, vd, vn, vm); 51210078Snilay@cs.wisc.edu } else { 51310121Snilay@cs.wisc.edu if (bits(machInst, 23) == 1) { 51410121Snilay@cs.wisc.edu if (q) { 51510121Snilay@cs.wisc.edu return new Unknown(machInst); 5166657Snate@binkert.org } else { 5176657Snate@binkert.org return decodeNeonUSThreeUSReg<Vabdl>( 5186882SBrad.Beckmann@amd.com u, size, machInst, vd, vn, vm); 5196882SBrad.Beckmann@amd.com } 5206882SBrad.Beckmann@amd.com } else { 52110121Snilay@cs.wisc.edu return decodeNeonUSThreeReg<VabdD, VabdQ>( 52210121Snilay@cs.wisc.edu q, u, size, machInst, vd, vn, vm); 5236882SBrad.Beckmann@amd.com } 5246877Ssteve.reinhardt@amd.com } 5256882SBrad.Beckmann@amd.com case 0x8: 52610308Snilay@cs.wisc.edu if (b) { 5276882SBrad.Beckmann@amd.com if (u) { 52810308Snilay@cs.wisc.edu return decodeNeonUThreeReg<VceqD, VceqQ>( 52910311Snilay@cs.wisc.edu q, size, machInst, vd, vn, vm); 53010308Snilay@cs.wisc.edu } else { 53110308Snilay@cs.wisc.edu return decodeNeonUThreeReg<VtstD, VtstQ>( 53210917Sbrandon.potter@amd.com q, size, machInst, vd, vn, vm); 5339595Snilay@cs.wisc.edu } 5349745Snilay@cs.wisc.edu } else { 5359745Snilay@cs.wisc.edu if (u) { 5369745Snilay@cs.wisc.edu return decodeNeonUThreeReg<NVsubD, NVsubQ>( 5379745Snilay@cs.wisc.edu q, size, machInst, vd, vn, vm); 5389745Snilay@cs.wisc.edu } else { 5399745Snilay@cs.wisc.edu return decodeNeonUThreeReg<NVaddD, NVaddQ>( 5409745Snilay@cs.wisc.edu q, size, machInst, vd, vn, vm); 5419745Snilay@cs.wisc.edu } 5429745Snilay@cs.wisc.edu } 5439745Snilay@cs.wisc.edu case 0x9: 5449595Snilay@cs.wisc.edu if (b) { 5456657Snate@binkert.org if (u) { 5466657Snate@binkert.org return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 5476657Snate@binkert.org q, size, machInst, vd, vn, vm); 5486657Snate@binkert.org } else { 5497007Snate@binkert.org return decodeNeonSThreeReg<NVmulD, NVmulQ>( 55011021Sjthestness@gmail.com q, size, machInst, vd, vn, vm); 55110311Snilay@cs.wisc.edu } 55210311Snilay@cs.wisc.edu } else { 55310311Snilay@cs.wisc.edu if (u) { 55410311Snilay@cs.wisc.edu return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 55510311Snilay@cs.wisc.edu q, u, size, machInst, vd, vn, vm); 55610311Snilay@cs.wisc.edu } else { 55710311Snilay@cs.wisc.edu return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 55810311Snilay@cs.wisc.edu q, u, size, machInst, vd, vn, vm); 55910311Snilay@cs.wisc.edu } 56010311Snilay@cs.wisc.edu } 56110311Snilay@cs.wisc.edu case 0xa: 56210311Snilay@cs.wisc.edu if (q) 56310311Snilay@cs.wisc.edu return new Unknown(machInst); 56411084Snilay@cs.wisc.edu if (b) { 56510311Snilay@cs.wisc.edu return decodeNeonUSThreeUSReg<VpminD>( 56610311Snilay@cs.wisc.edu u, size, machInst, vd, vn, vm); 56711021Sjthestness@gmail.com } else { 56811021Sjthestness@gmail.com return decodeNeonUSThreeUSReg<VpmaxD>( 56910311Snilay@cs.wisc.edu u, size, machInst, vd, vn, vm); 57010311Snilay@cs.wisc.edu } 57110311Snilay@cs.wisc.edu case 0xb: 57210311Snilay@cs.wisc.edu if (b) { 57310311Snilay@cs.wisc.edu if (u || q) { 57410311Snilay@cs.wisc.edu return new Unknown(machInst); 57510311Snilay@cs.wisc.edu } else { 57610311Snilay@cs.wisc.edu return decodeNeonUThreeUSReg<NVpaddD>( 57710311Snilay@cs.wisc.edu size, machInst, vd, vn, vm); 57810311Snilay@cs.wisc.edu } 57910311Snilay@cs.wisc.edu } else { 58011021Sjthestness@gmail.com if (u) { 58111021Sjthestness@gmail.com return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>( 58210311Snilay@cs.wisc.edu q, size, machInst, vd, vn, vm); 58310311Snilay@cs.wisc.edu } else { 58410311Snilay@cs.wisc.edu return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>( 58510311Snilay@cs.wisc.edu q, size, machInst, vd, vn, vm); 58610311Snilay@cs.wisc.edu } 58710311Snilay@cs.wisc.edu } 58810311Snilay@cs.wisc.edu case 0xc: 58910311Snilay@cs.wisc.edu if (b) { 59010311Snilay@cs.wisc.edu if (!u) { 59110311Snilay@cs.wisc.edu if (bits(c, 1) == 0) { 5927007Snate@binkert.org if (q) { 5936657Snate@binkert.org return new NVfmaQFp<float>(machInst, vd, vn, vm); 5947007Snate@binkert.org } else { 59511021Sjthestness@gmail.com return new NVfmaDFp<float>(machInst, vd, vn, vm); 5966657Snate@binkert.org } 5976657Snate@binkert.org } else { 5986657Snate@binkert.org if (q) { 59910311Snilay@cs.wisc.edu return new NVfmsQFp<float>(machInst, vd, vn, vm); 6006657Snate@binkert.org } else { 6016657Snate@binkert.org return new NVfmsDFp<float>(machInst, vd, vn, vm); 60210305Snilay@cs.wisc.edu } 6036657Snate@binkert.org } 6046657Snate@binkert.org } 6056657Snate@binkert.org } 6066657Snate@binkert.org return new Unknown(machInst); 6076657Snate@binkert.org case 0xd: 6086657Snate@binkert.org if (b) { 6096657Snate@binkert.org if (u) { 6106657Snate@binkert.org if (bits(c, 1) == 0) { 61111084Snilay@cs.wisc.edu if (q) { 61211084Snilay@cs.wisc.edu return new NVmulQFp<float>(machInst, vd, vn, vm); 61311084Snilay@cs.wisc.edu } else { 61411084Snilay@cs.wisc.edu return new NVmulDFp<float>(machInst, vd, vn, vm); 61511084Snilay@cs.wisc.edu } 6166657Snate@binkert.org } else { 61711084Snilay@cs.wisc.edu return new Unknown(machInst); 6186657Snate@binkert.org } 6196657Snate@binkert.org } else { 6206657Snate@binkert.org if (bits(c, 1) == 0) { 6217007Snate@binkert.org if (q) { 6226657Snate@binkert.org return new NVmlaQFp<float>(machInst, vd, vn, vm); 6237007Snate@binkert.org } else { 6247007Snate@binkert.org return new NVmlaDFp<float>(machInst, vd, vn, vm); 6256657Snate@binkert.org } 6269366Snilay@cs.wisc.edu } else { 6279366Snilay@cs.wisc.edu if (q) { 6289366Snilay@cs.wisc.edu return new NVmlsQFp<float>(machInst, vd, vn, vm); 6299366Snilay@cs.wisc.edu } else { 6307566SBrad.Beckmann@amd.com return new NVmlsDFp<float>(machInst, vd, vn, vm); 6317672Snate@binkert.org } 6326657Snate@binkert.org } 6339465Snilay@cs.wisc.edu } 6346657Snate@binkert.org } else { 6356657Snate@binkert.org if (u) { 6366657Snate@binkert.org if (bits(c, 1) == 0) { 6377672Snate@binkert.org if (q) { 6386657Snate@binkert.org return new VpaddQFp<float>(machInst, vd, vn, vm); 6396657Snate@binkert.org } else { 6406657Snate@binkert.org return new VpaddDFp<float>(machInst, vd, vn, vm); 6416657Snate@binkert.org } 6426657Snate@binkert.org } else { 6436657Snate@binkert.org if (q) { 6446657Snate@binkert.org return new VabdQFp<float>(machInst, vd, vn, vm); 6456657Snate@binkert.org } else { 6466657Snate@binkert.org return new VabdDFp<float>(machInst, vd, vn, vm); 6476657Snate@binkert.org } 6486657Snate@binkert.org } 6499745Snilay@cs.wisc.edu } else { 6506657Snate@binkert.org if (bits(c, 1) == 0) { 6516657Snate@binkert.org if (q) { 6529496Snilay@cs.wisc.edu return new VaddQFp<float>(machInst, vd, vn, vm); 6539496Snilay@cs.wisc.edu } else { 65410012Snilay@cs.wisc.edu return new VaddDFp<float>(machInst, vd, vn, vm); 6559496Snilay@cs.wisc.edu } 6569496Snilay@cs.wisc.edu } else { 6576657Snate@binkert.org if (q) { 65810121Snilay@cs.wisc.edu return new VsubQFp<float>(machInst, vd, vn, vm); 6596657Snate@binkert.org } else { 6606657Snate@binkert.org return new VsubDFp<float>(machInst, vd, vn, vm); 66110305Snilay@cs.wisc.edu } 6626657Snate@binkert.org } 66311021Sjthestness@gmail.com } 66411021Sjthestness@gmail.com } 66511021Sjthestness@gmail.com case 0xe: 66611021Sjthestness@gmail.com if (b) { 66711021Sjthestness@gmail.com if (u) { 6688683Snilay@cs.wisc.edu if (bits(c, 1) == 0) { 6698683Snilay@cs.wisc.edu if (q) { 67010308Snilay@cs.wisc.edu return new VacgeQFp<float>(machInst, vd, vn, vm); 6718683Snilay@cs.wisc.edu } else { 67210308Snilay@cs.wisc.edu return new VacgeDFp<float>(machInst, vd, vn, vm); 6738683Snilay@cs.wisc.edu } 6746657Snate@binkert.org } else { 6759745Snilay@cs.wisc.edu if (q) { 6769745Snilay@cs.wisc.edu return new VacgtQFp<float>(machInst, vd, vn, vm); 6779745Snilay@cs.wisc.edu } else { 6789745Snilay@cs.wisc.edu return new VacgtDFp<float>(machInst, vd, vn, vm); 67910012Snilay@cs.wisc.edu } 68010012Snilay@cs.wisc.edu } 6819745Snilay@cs.wisc.edu } else { 6829745Snilay@cs.wisc.edu return new Unknown(machInst); 6839745Snilay@cs.wisc.edu } 6849745Snilay@cs.wisc.edu } else { 6859745Snilay@cs.wisc.edu if (u) { 68610919Sbrandon.potter@amd.com if (bits(c, 1) == 0) { 68710012Snilay@cs.wisc.edu if (q) { 6889745Snilay@cs.wisc.edu return new VcgeQFp<float>(machInst, vd, vn, vm); 6899745Snilay@cs.wisc.edu } else { 6909745Snilay@cs.wisc.edu return new VcgeDFp<float>(machInst, vd, vn, vm); 6919745Snilay@cs.wisc.edu } 6929745Snilay@cs.wisc.edu } else { 6939745Snilay@cs.wisc.edu if (q) { 6949745Snilay@cs.wisc.edu return new VcgtQFp<float>(machInst, vd, vn, vm); 6959745Snilay@cs.wisc.edu } else { 6969745Snilay@cs.wisc.edu return new VcgtDFp<float>(machInst, vd, vn, vm); 6979745Snilay@cs.wisc.edu } 6989745Snilay@cs.wisc.edu } 6999745Snilay@cs.wisc.edu } else { 7009745Snilay@cs.wisc.edu if (bits(c, 1) == 0) { 7019745Snilay@cs.wisc.edu if (q) { 7029745Snilay@cs.wisc.edu return new VceqQFp<float>(machInst, vd, vn, vm); 7039745Snilay@cs.wisc.edu } else { 70410919Sbrandon.potter@amd.com return new VceqDFp<float>(machInst, vd, vn, vm); 70510012Snilay@cs.wisc.edu } 7069745Snilay@cs.wisc.edu } else { 7079745Snilay@cs.wisc.edu return new Unknown(machInst); 7089745Snilay@cs.wisc.edu } 7099745Snilay@cs.wisc.edu } 7109745Snilay@cs.wisc.edu } 7119745Snilay@cs.wisc.edu case 0xf: 7129745Snilay@cs.wisc.edu if (b) { 7139745Snilay@cs.wisc.edu if (u) { 7149745Snilay@cs.wisc.edu return new Unknown(machInst); 7159745Snilay@cs.wisc.edu } else { 7169745Snilay@cs.wisc.edu if (bits(c, 1) == 0) { 7179745Snilay@cs.wisc.edu if (q) { 7189745Snilay@cs.wisc.edu return new VrecpsQFp<float>(machInst, vd, vn, vm); 7199745Snilay@cs.wisc.edu } else { 7209745Snilay@cs.wisc.edu return new VrecpsDFp<float>(machInst, vd, vn, vm); 7219745Snilay@cs.wisc.edu } 72210920Sbrandon.potter@amd.com } else { 7239745Snilay@cs.wisc.edu if (q) { 72410920Sbrandon.potter@amd.com return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 72510920Sbrandon.potter@amd.com } else { 7269745Snilay@cs.wisc.edu return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 7279745Snilay@cs.wisc.edu } 7289745Snilay@cs.wisc.edu } 7299745Snilay@cs.wisc.edu } 7309745Snilay@cs.wisc.edu } else { 7319745Snilay@cs.wisc.edu if (u) { 7329745Snilay@cs.wisc.edu if (bits(c, 1) == 0) { 7339745Snilay@cs.wisc.edu if (q) { 7349745Snilay@cs.wisc.edu return new VpmaxQFp<float>(machInst, vd, vn, vm); 7359745Snilay@cs.wisc.edu } else { 7369745Snilay@cs.wisc.edu return new VpmaxDFp<float>(machInst, vd, vn, vm); 7379745Snilay@cs.wisc.edu } 73810920Sbrandon.potter@amd.com } else { 7399745Snilay@cs.wisc.edu if (q) { 74010920Sbrandon.potter@amd.com return new VpminQFp<float>(machInst, vd, vn, vm); 74110920Sbrandon.potter@amd.com } else { 7429745Snilay@cs.wisc.edu return new VpminDFp<float>(machInst, vd, vn, vm); 7439745Snilay@cs.wisc.edu } 7449745Snilay@cs.wisc.edu } 7459745Snilay@cs.wisc.edu } else { 7469745Snilay@cs.wisc.edu if (bits(c, 1) == 0) { 7479745Snilay@cs.wisc.edu if (q) { 7489745Snilay@cs.wisc.edu return new VmaxQFp<float>(machInst, vd, vn, vm); 7499745Snilay@cs.wisc.edu } else { 7509745Snilay@cs.wisc.edu return new VmaxDFp<float>(machInst, vd, vn, vm); 7519745Snilay@cs.wisc.edu } 7529745Snilay@cs.wisc.edu } else { 7539745Snilay@cs.wisc.edu if (q) { 7549745Snilay@cs.wisc.edu return new VminQFp<float>(machInst, vd, vn, vm); 7559745Snilay@cs.wisc.edu } else { 7569745Snilay@cs.wisc.edu return new VminDFp<float>(machInst, vd, vn, vm); 7579745Snilay@cs.wisc.edu } 7589745Snilay@cs.wisc.edu } 7599745Snilay@cs.wisc.edu } 7609745Snilay@cs.wisc.edu } 7619745Snilay@cs.wisc.edu } 7629745Snilay@cs.wisc.edu return new Unknown(machInst); 76311061Snilay@cs.wisc.edu } 7649745Snilay@cs.wisc.edu 7659745Snilay@cs.wisc.edu static StaticInstPtr 7669745Snilay@cs.wisc.edu decodeNeonOneRegModImm(ExtMachInst machInst) 7679745Snilay@cs.wisc.edu { 7689745Snilay@cs.wisc.edu const IntRegIndex vd = 7699745Snilay@cs.wisc.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 7709745Snilay@cs.wisc.edu (bits(machInst, 22) << 4))); 7719745Snilay@cs.wisc.edu const bool q = bits(machInst, 6); 7729745Snilay@cs.wisc.edu const bool op = bits(machInst, 5); 7739745Snilay@cs.wisc.edu const uint8_t cmode = bits(machInst, 11, 8); 7749745Snilay@cs.wisc.edu const uint8_t imm = ((THUMB ? bits(machInst, 28) : 77511061Snilay@cs.wisc.edu bits(machInst, 24)) << 7) | 7769745Snilay@cs.wisc.edu (bits(machInst, 18, 16) << 4) | 7779745Snilay@cs.wisc.edu (bits(machInst, 3, 0) << 0); 7789745Snilay@cs.wisc.edu 7799745Snilay@cs.wisc.edu // Check for invalid immediate encodings and return an unknown op 7809745Snilay@cs.wisc.edu // if it happens 7819745Snilay@cs.wisc.edu bool immValid = true; 7827007Snate@binkert.org const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid); 7837007Snate@binkert.org if (!immValid) { 7847007Snate@binkert.org return new Unknown(machInst); 7856657Snate@binkert.org } 7866657Snate@binkert.org 7876657Snate@binkert.org if (op) { 7887007Snate@binkert.org if (bits(cmode, 3) == 0) { 7897007Snate@binkert.org if (bits(cmode, 0) == 0) { 7907007Snate@binkert.org if (q) 7916657Snate@binkert.org return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 7926657Snate@binkert.org else 7936657Snate@binkert.org return new NVmvniD<uint64_t>(machInst, vd, bigImm); 79411021Sjthestness@gmail.com } else { 79511021Sjthestness@gmail.com if (q) 79611021Sjthestness@gmail.com return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 79711021Sjthestness@gmail.com else 79811021Sjthestness@gmail.com return new NVbiciD<uint64_t>(machInst, vd, bigImm); 79911021Sjthestness@gmail.com } 8008683Snilay@cs.wisc.edu } else { 8018683Snilay@cs.wisc.edu if (bits(cmode, 2) == 1) { 8028683Snilay@cs.wisc.edu switch (bits(cmode, 1, 0)) { 8038683Snilay@cs.wisc.edu case 0: 8048683Snilay@cs.wisc.edu case 1: 8058683Snilay@cs.wisc.edu if (q) 8067007Snate@binkert.org return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 8077007Snate@binkert.org else 8087007Snate@binkert.org return new NVmvniD<uint64_t>(machInst, vd, bigImm); 8097007Snate@binkert.org case 2: 8107007Snate@binkert.org if (q) 8116657Snate@binkert.org return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 81210012Snilay@cs.wisc.edu else 8139745Snilay@cs.wisc.edu return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8149745Snilay@cs.wisc.edu case 3: 8159745Snilay@cs.wisc.edu if (q) 8169745Snilay@cs.wisc.edu return new Unknown(machInst); 8179745Snilay@cs.wisc.edu else 8189745Snilay@cs.wisc.edu return new Unknown(machInst); 8196902SBrad.Beckmann@amd.com } 8209745Snilay@cs.wisc.edu } else { 8219745Snilay@cs.wisc.edu if (bits(cmode, 0) == 0) { 8229745Snilay@cs.wisc.edu if (q) 8239745Snilay@cs.wisc.edu return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 82410012Snilay@cs.wisc.edu else 8256902SBrad.Beckmann@amd.com return new NVmvniD<uint64_t>(machInst, vd, bigImm); 8267839Snilay@cs.wisc.edu } else { 8277839Snilay@cs.wisc.edu if (q) 8287839Snilay@cs.wisc.edu return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 8297839Snilay@cs.wisc.edu else 8307839Snilay@cs.wisc.edu return new NVbiciD<uint64_t>(machInst, vd, bigImm); 8317839Snilay@cs.wisc.edu } 8327839Snilay@cs.wisc.edu } 8337839Snilay@cs.wisc.edu } 8347839Snilay@cs.wisc.edu } else { 8357839Snilay@cs.wisc.edu if (bits(cmode, 3) == 0) { 8367839Snilay@cs.wisc.edu if (bits(cmode, 0) == 0) { 8377839Snilay@cs.wisc.edu if (q) 8387839Snilay@cs.wisc.edu return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8397839Snilay@cs.wisc.edu else 8407839Snilay@cs.wisc.edu return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8417839Snilay@cs.wisc.edu } else { 8427839Snilay@cs.wisc.edu if (q) 8437839Snilay@cs.wisc.edu return new NVorriQ<uint64_t>(machInst, vd, bigImm); 8447839Snilay@cs.wisc.edu else 8457839Snilay@cs.wisc.edu return new NVorriD<uint64_t>(machInst, vd, bigImm); 8467839Snilay@cs.wisc.edu } 8477839Snilay@cs.wisc.edu } else { 8487839Snilay@cs.wisc.edu if (bits(cmode, 2) == 1) { 8497839Snilay@cs.wisc.edu if (q) 8507839Snilay@cs.wisc.edu return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8517839Snilay@cs.wisc.edu else 8527839Snilay@cs.wisc.edu return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8537839Snilay@cs.wisc.edu } else { 8547839Snilay@cs.wisc.edu if (bits(cmode, 0) == 0) { 8557839Snilay@cs.wisc.edu if (q) 8567839Snilay@cs.wisc.edu return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8577839Snilay@cs.wisc.edu else 8587839Snilay@cs.wisc.edu return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8597839Snilay@cs.wisc.edu } else { 8607839Snilay@cs.wisc.edu if (q) 8617839Snilay@cs.wisc.edu return new NVorriQ<uint64_t>(machInst, vd, bigImm); 8627839Snilay@cs.wisc.edu else 8636902SBrad.Beckmann@amd.com return new NVorriD<uint64_t>(machInst, vd, bigImm); 8648683Snilay@cs.wisc.edu } 8658683Snilay@cs.wisc.edu } 8668683Snilay@cs.wisc.edu } 8678683Snilay@cs.wisc.edu } 8688683Snilay@cs.wisc.edu return new Unknown(machInst); 8698683Snilay@cs.wisc.edu } 8708683Snilay@cs.wisc.edu 8718683Snilay@cs.wisc.edu static StaticInstPtr 8728683Snilay@cs.wisc.edu decodeNeonTwoRegAndShift(ExtMachInst machInst) 8738683Snilay@cs.wisc.edu { 8748683Snilay@cs.wisc.edu const uint32_t a = bits(machInst, 11, 8); 8758683Snilay@cs.wisc.edu const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 8768683Snilay@cs.wisc.edu const bool b = bits(machInst, 6); 8778683Snilay@cs.wisc.edu const bool l = bits(machInst, 7); 8788683Snilay@cs.wisc.edu const IntRegIndex vd = 8798683Snilay@cs.wisc.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 8808683Snilay@cs.wisc.edu (bits(machInst, 22) << 4))); 8816657Snate@binkert.org const IntRegIndex vm = 8826657Snate@binkert.org (IntRegIndex)(2 * (bits(machInst, 3, 0) | 8837839Snilay@cs.wisc.edu (bits(machInst, 5) << 4))); 8847839Snilay@cs.wisc.edu unsigned imm6 = bits(machInst, 21, 16); 8857839Snilay@cs.wisc.edu unsigned imm = ((l ? 1 : 0) << 6) | imm6; 8867839Snilay@cs.wisc.edu unsigned size = 3; 8876657Snate@binkert.org unsigned lShiftAmt = 0; 8887839Snilay@cs.wisc.edu unsigned bitSel; 8897839Snilay@cs.wisc.edu for (bitSel = 1 << 6; true; bitSel >>= 1) { 8907839Snilay@cs.wisc.edu if (bitSel & imm) 89111025Snilay@cs.wisc.edu break; 8927839Snilay@cs.wisc.edu else if (!size) 8938055Sksewell@umich.edu return new Unknown(machInst); 89410963Sdavid.hashe@amd.com size--; 89510963Sdavid.hashe@amd.com } 89610963Sdavid.hashe@amd.com lShiftAmt = imm6 & ~bitSel; 89710963Sdavid.hashe@amd.com unsigned rShiftAmt = 0; 89810963Sdavid.hashe@amd.com if (a != 0xe && a != 0xf) { 89910963Sdavid.hashe@amd.com if (size > 2) 90010963Sdavid.hashe@amd.com rShiftAmt = 64 - imm6; 9017839Snilay@cs.wisc.edu else 9026657Snate@binkert.org rShiftAmt = 2 * (8 << size) - imm6; 9037839Snilay@cs.wisc.edu } 9047839Snilay@cs.wisc.edu 9057839Snilay@cs.wisc.edu switch (a) { 9067839Snilay@cs.wisc.edu case 0x0: 9077839Snilay@cs.wisc.edu return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 9087839Snilay@cs.wisc.edu b, u, size, machInst, vd, vm, rShiftAmt); 9097839Snilay@cs.wisc.edu case 0x1: 9107839Snilay@cs.wisc.edu return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 9117839Snilay@cs.wisc.edu b, u, size, machInst, vd, vm, rShiftAmt); 91211025Snilay@cs.wisc.edu case 0x2: 9137839Snilay@cs.wisc.edu return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 9148055Sksewell@umich.edu b, u, size, machInst, vd, vm, rShiftAmt); 9157839Snilay@cs.wisc.edu case 0x3: 9167839Snilay@cs.wisc.edu return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 9177839Snilay@cs.wisc.edu b, u, size, machInst, vd, vm, rShiftAmt); 9187839Snilay@cs.wisc.edu case 0x4: 9197839Snilay@cs.wisc.edu if (u) { 9207839Snilay@cs.wisc.edu return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 9217839Snilay@cs.wisc.edu b, size, machInst, vd, vm, rShiftAmt); 9227839Snilay@cs.wisc.edu } else { 9237839Snilay@cs.wisc.edu return new Unknown(machInst); 9247839Snilay@cs.wisc.edu } 9257839Snilay@cs.wisc.edu case 0x5: 9267839Snilay@cs.wisc.edu if (u) { 92711025Snilay@cs.wisc.edu return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 9287839Snilay@cs.wisc.edu b, size, machInst, vd, vm, lShiftAmt); 9298055Sksewell@umich.edu } else { 9307839Snilay@cs.wisc.edu return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 9317839Snilay@cs.wisc.edu b, size, machInst, vd, vm, lShiftAmt); 9327839Snilay@cs.wisc.edu } 9337839Snilay@cs.wisc.edu case 0x6: 9347839Snilay@cs.wisc.edu case 0x7: 9357839Snilay@cs.wisc.edu if (u) { 9367839Snilay@cs.wisc.edu if (a == 0x6) { 9377839Snilay@cs.wisc.edu return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 9387839Snilay@cs.wisc.edu b, size, machInst, vd, vm, lShiftAmt); 9397839Snilay@cs.wisc.edu } else { 9406657Snate@binkert.org return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 9417007Snate@binkert.org b, size, machInst, vd, vm, lShiftAmt); 94211025Snilay@cs.wisc.edu } 9436657Snate@binkert.org } else { 9448055Sksewell@umich.edu return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 9456657Snate@binkert.org b, size, machInst, vd, vm, lShiftAmt); 9466657Snate@binkert.org } 9476657Snate@binkert.org case 0x8: 9486657Snate@binkert.org if (l) { 9498478Snilay@cs.wisc.edu return new Unknown(machInst); 9508478Snilay@cs.wisc.edu } else if (u) { 9518478Snilay@cs.wisc.edu return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 9529302Snilay@cs.wisc.edu b, size, machInst, vd, vm, rShiftAmt); 9539302Snilay@cs.wisc.edu } else { 95410524Snilay@cs.wisc.edu return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 9559302Snilay@cs.wisc.edu b, size, machInst, vd, vm, rShiftAmt); 9569302Snilay@cs.wisc.edu } 95710524Snilay@cs.wisc.edu case 0x9: 9589302Snilay@cs.wisc.edu if (l) { 9599302Snilay@cs.wisc.edu return new Unknown(machInst); 9609302Snilay@cs.wisc.edu } else if (u) { 9619302Snilay@cs.wisc.edu return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 96210305Snilay@cs.wisc.edu b, size, machInst, vd, vm, rShiftAmt); 9639302Snilay@cs.wisc.edu } else { 96410311Snilay@cs.wisc.edu return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 96510311Snilay@cs.wisc.edu b, size, machInst, vd, vm, rShiftAmt); 96610311Snilay@cs.wisc.edu } 96710311Snilay@cs.wisc.edu case 0xa: 96810311Snilay@cs.wisc.edu if (l || b) { 96910311Snilay@cs.wisc.edu return new Unknown(machInst); 97010311Snilay@cs.wisc.edu } else { 9719302Snilay@cs.wisc.edu return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 9729302Snilay@cs.wisc.edu lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); 9739302Snilay@cs.wisc.edu } 9749302Snilay@cs.wisc.edu case 0xe: 9759302Snilay@cs.wisc.edu if (l) { 9766657Snate@binkert.org return new Unknown(machInst); 9776657Snate@binkert.org } else { 9789219Spower.jg@gmail.com if (bits(imm6, 5) == 0) 9796657Snate@binkert.org return new Unknown(machInst); 9806657Snate@binkert.org if (u) { 9816999Snate@binkert.org if (b) { 9826657Snate@binkert.org return new NVcvtu2fpQ<float>( 9836657Snate@binkert.org machInst, vd, vm, 64 - imm6); 9849104Shestness@cs.utexas.edu } else { 9859104Shestness@cs.utexas.edu return new NVcvtu2fpD<float>( 9869104Shestness@cs.utexas.edu machInst, vd, vm, 64 - imm6); 9879104Shestness@cs.utexas.edu } 9886657Snate@binkert.org } else { 9896657Snate@binkert.org if (b) { 9906657Snate@binkert.org return new NVcvts2fpQ<float>( 9916657Snate@binkert.org machInst, vd, vm, 64 - imm6); 9928946Sandreas.hansson@arm.com } else { 9938946Sandreas.hansson@arm.com return new NVcvts2fpD<float>( 9948946Sandreas.hansson@arm.com machInst, vd, vm, 64 - imm6); 9957832Snate@binkert.org } 99610972Sdavid.hashe@amd.com } 9977832Snate@binkert.org } 9987007Snate@binkert.org case 0xf: 99910972Sdavid.hashe@amd.com if (l) { 100010972Sdavid.hashe@amd.com return new Unknown(machInst); 100110972Sdavid.hashe@amd.com } else { 100210972Sdavid.hashe@amd.com if (bits(imm6, 5) == 0) 100310972Sdavid.hashe@amd.com return new Unknown(machInst); 10048229Snate@binkert.org if (u) { 10058229Snate@binkert.org if (b) { 10068229Snate@binkert.org return new NVcvt2ufxQ<float>( 100710972Sdavid.hashe@amd.com machInst, vd, vm, 64 - imm6); 10089104Shestness@cs.utexas.edu } else { 10099104Shestness@cs.utexas.edu return new NVcvt2ufxD<float>( 10109104Shestness@cs.utexas.edu machInst, vd, vm, 64 - imm6); 10119104Shestness@cs.utexas.edu } 10129104Shestness@cs.utexas.edu } else { 10139104Shestness@cs.utexas.edu if (b) { 10148229Snate@binkert.org return new NVcvt2sfxQ<float>( 101511108Sdavid.hashe@amd.com machInst, vd, vm, 64 - imm6); 101610972Sdavid.hashe@amd.com } else { 10179219Spower.jg@gmail.com return new NVcvt2sfxD<float>( 10189219Spower.jg@gmail.com machInst, vd, vm, 64 - imm6); 10199219Spower.jg@gmail.com } 10209219Spower.jg@gmail.com } 10219219Spower.jg@gmail.com } 10229219Spower.jg@gmail.com } 102310963Sdavid.hashe@amd.com return new Unknown(machInst); 102410963Sdavid.hashe@amd.com } 10259219Spower.jg@gmail.com 10266657Snate@binkert.org static StaticInstPtr 10277055Snate@binkert.org decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 10287055Snate@binkert.org { 10297007Snate@binkert.org const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 10307007Snate@binkert.org const uint32_t a = bits(machInst, 11, 8); 10316657Snate@binkert.org const IntRegIndex vd = 10326657Snate@binkert.org (IntRegIndex)(2 * (bits(machInst, 15, 12) | 10336657Snate@binkert.org (bits(machInst, 22) << 4))); 103410963Sdavid.hashe@amd.com const IntRegIndex vn = 103510963Sdavid.hashe@amd.com (IntRegIndex)(2 * (bits(machInst, 19, 16) | 10366657Snate@binkert.org (bits(machInst, 7) << 4))); 10376657Snate@binkert.org const IntRegIndex vm = 10386657Snate@binkert.org (IntRegIndex)(2 * (bits(machInst, 3, 0) | 10397007Snate@binkert.org (bits(machInst, 5) << 4))); 10409496Snilay@cs.wisc.edu const unsigned size = bits(machInst, 21, 20); 10417007Snate@binkert.org switch (a) { 10427007Snate@binkert.org case 0x0: 10439499Snilay@cs.wisc.edu return decodeNeonUSThreeUSReg<Vaddl>( 10446657Snate@binkert.org u, size, machInst, vd, vn, vm); 10456657Snate@binkert.org case 0x1: 10466657Snate@binkert.org return decodeNeonUSThreeUSReg<Vaddw>( 10476657Snate@binkert.org u, size, machInst, vd, vn, vm); 10486657Snate@binkert.org case 0x2: 10496657Snate@binkert.org return decodeNeonUSThreeUSReg<Vsubl>( 10506657Snate@binkert.org u, size, machInst, vd, vn, vm); 10516657Snate@binkert.org case 0x3: 10526657Snate@binkert.org return decodeNeonUSThreeUSReg<Vsubw>( 10536657Snate@binkert.org u, size, machInst, vd, vn, vm); 10546657Snate@binkert.org case 0x4: 10556657Snate@binkert.org if (u) { 10567567SBrad.Beckmann@amd.com return decodeNeonUThreeUSReg<Vraddhn>( 10579996Snilay@cs.wisc.edu size, machInst, vd, vn, vm); 10587567SBrad.Beckmann@amd.com } else { 10599996Snilay@cs.wisc.edu return decodeNeonUThreeUSReg<Vaddhn>( 106010963Sdavid.hashe@amd.com size, machInst, vd, vn, vm); 106110963Sdavid.hashe@amd.com } 106210963Sdavid.hashe@amd.com case 0x5: 10636657Snate@binkert.org return decodeNeonUSThreeUSReg<Vabal>( 106410963Sdavid.hashe@amd.com u, size, machInst, vd, vn, vm); 106510963Sdavid.hashe@amd.com case 0x6: 106610963Sdavid.hashe@amd.com if (u) { 106710963Sdavid.hashe@amd.com return decodeNeonUThreeUSReg<Vrsubhn>( 106810963Sdavid.hashe@amd.com size, machInst, vd, vn, vm); 106910963Sdavid.hashe@amd.com } else { 107010963Sdavid.hashe@amd.com return decodeNeonUThreeUSReg<Vsubhn>( 107110963Sdavid.hashe@amd.com size, machInst, vd, vn, vm); 10726657Snate@binkert.org } 10736657Snate@binkert.org case 0x7: 10746657Snate@binkert.org if (bits(machInst, 23)) { 10756657Snate@binkert.org return decodeNeonUSThreeUSReg<Vabdl>( 10766657Snate@binkert.org u, size, machInst, vd, vn, vm); 10776657Snate@binkert.org } else { 107810963Sdavid.hashe@amd.com return decodeNeonUSThreeReg<VabdD, VabdQ>( 107910963Sdavid.hashe@amd.com bits(machInst, 6), u, size, machInst, vd, vn, vm); 108010963Sdavid.hashe@amd.com } 108110963Sdavid.hashe@amd.com case 0x8: 108210963Sdavid.hashe@amd.com return decodeNeonUSThreeUSReg<Vmlal>( 108310963Sdavid.hashe@amd.com u, size, machInst, vd, vn, vm); 108410963Sdavid.hashe@amd.com case 0xa: 108510963Sdavid.hashe@amd.com return decodeNeonUSThreeUSReg<Vmlsl>( 108610963Sdavid.hashe@amd.com u, size, machInst, vd, vn, vm); 108710963Sdavid.hashe@amd.com case 0x9: 108810963Sdavid.hashe@amd.com if (u) { 108910963Sdavid.hashe@amd.com return new Unknown(machInst); 109010963Sdavid.hashe@amd.com } else { 109110963Sdavid.hashe@amd.com return decodeNeonSThreeUSReg<Vqdmlal>( 109210963Sdavid.hashe@amd.com size, machInst, vd, vn, vm); 109310963Sdavid.hashe@amd.com } 109410963Sdavid.hashe@amd.com case 0xb: 109510963Sdavid.hashe@amd.com if (u) { 109610963Sdavid.hashe@amd.com return new Unknown(machInst); 10976657Snate@binkert.org } else { 10986657Snate@binkert.org return decodeNeonSThreeUSReg<Vqdmlsl>( 10996657Snate@binkert.org size, machInst, vd, vn, vm); 11006657Snate@binkert.org } 11016657Snate@binkert.org case 0xc: 11026657Snate@binkert.org return decodeNeonUSThreeUSReg<Vmull>( 11036657Snate@binkert.org u, size, machInst, vd, vn, vm); 11046657Snate@binkert.org case 0xd: 11056657Snate@binkert.org if (u) { 11066999Snate@binkert.org return new Unknown(machInst); 11076657Snate@binkert.org } else { 11086657Snate@binkert.org return decodeNeonSThreeUSReg<Vqdmull>( 11096657Snate@binkert.org size, machInst, vd, vn, vm); 11106657Snate@binkert.org } 11116657Snate@binkert.org case 0xe: 11126657Snate@binkert.org return decodeNeonUThreeUSReg<Vmullp>( 11137832Snate@binkert.org size, machInst, vd, vn, vm); 11147832Snate@binkert.org } 11157805Snilay@cs.wisc.edu return new Unknown(machInst); 11167832Snate@binkert.org } 11178232Snate@binkert.org 11188232Snate@binkert.org static StaticInstPtr 11198229Snate@binkert.org decodeNeonTwoRegScalar(ExtMachInst machInst) 11208229Snate@binkert.org { 11218229Snate@binkert.org const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 11228229Snate@binkert.org const uint32_t a = bits(machInst, 11, 8); 112311108Sdavid.hashe@amd.com const unsigned size = bits(machInst, 21, 20); 11246657Snate@binkert.org const IntRegIndex vd = 11256657Snate@binkert.org (IntRegIndex)(2 * (bits(machInst, 15, 12) | 11266657Snate@binkert.org (bits(machInst, 22) << 4))); 11276657Snate@binkert.org const IntRegIndex vn = 11286657Snate@binkert.org (IntRegIndex)(2 * (bits(machInst, 19, 16) | 11296657Snate@binkert.org (bits(machInst, 7) << 4))); 11307007Snate@binkert.org const IntRegIndex vm = (size == 2) ? 11317007Snate@binkert.org (IntRegIndex)(2 * bits(machInst, 3, 0)) : 11327839Snilay@cs.wisc.edu (IntRegIndex)(2 * bits(machInst, 2, 0)); 11337839Snilay@cs.wisc.edu const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 11347839Snilay@cs.wisc.edu (bits(machInst, 3) | (bits(machInst, 5) << 1)); 11357839Snilay@cs.wisc.edu switch (a) { 11367839Snilay@cs.wisc.edu case 0x0: 11377839Snilay@cs.wisc.edu if (u) { 11387839Snilay@cs.wisc.edu switch (size) { 11397839Snilay@cs.wisc.edu case 1: 11407839Snilay@cs.wisc.edu return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 11417839Snilay@cs.wisc.edu case 2: 114211025Snilay@cs.wisc.edu return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index); 11436657Snate@binkert.org default: 11447839Snilay@cs.wisc.edu return new Unknown(machInst); 114510305Snilay@cs.wisc.edu } 114610305Snilay@cs.wisc.edu } else { 11477839Snilay@cs.wisc.edu switch (size) { 11488337Snilay@cs.wisc.edu case 1: 11497839Snilay@cs.wisc.edu return new VmlasD<uint16_t>(machInst, vd, vn, vm, index); 11508337Snilay@cs.wisc.edu case 2: 11517839Snilay@cs.wisc.edu return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 11528337Snilay@cs.wisc.edu default: 11537839Snilay@cs.wisc.edu return new Unknown(machInst); 11548337Snilay@cs.wisc.edu } 11557839Snilay@cs.wisc.edu } 11567839Snilay@cs.wisc.edu case 0x1: 115710305Snilay@cs.wisc.edu if (u) 11586657Snate@binkert.org return new VmlasQFp<float>(machInst, vd, vn, vm, index); 115910305Snilay@cs.wisc.edu else 116010305Snilay@cs.wisc.edu return new VmlasDFp<float>(machInst, vd, vn, vm, index); 116110305Snilay@cs.wisc.edu case 0x4: 11626657Snate@binkert.org if (u) { 116310305Snilay@cs.wisc.edu switch (size) { 11647839Snilay@cs.wisc.edu case 1: 11657839Snilay@cs.wisc.edu return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 11667839Snilay@cs.wisc.edu case 2: 11677839Snilay@cs.wisc.edu return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index); 11687839Snilay@cs.wisc.edu default: 11697839Snilay@cs.wisc.edu return new Unknown(machInst); 11707839Snilay@cs.wisc.edu } 11717839Snilay@cs.wisc.edu } else { 11727839Snilay@cs.wisc.edu switch (size) { 11736657Snate@binkert.org case 1: 117411049Snilay@cs.wisc.edu return new VmlssD<uint16_t>(machInst, vd, vn, vm, index); 117511049Snilay@cs.wisc.edu case 2: 11767839Snilay@cs.wisc.edu return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 11776657Snate@binkert.org default: 117810305Snilay@cs.wisc.edu return new Unknown(machInst); 117910305Snilay@cs.wisc.edu } 118010305Snilay@cs.wisc.edu } 118110305Snilay@cs.wisc.edu case 0x5: 118210305Snilay@cs.wisc.edu if (u) 118311025Snilay@cs.wisc.edu return new VmlssQFp<float>(machInst, vd, vn, vm, index); 118410305Snilay@cs.wisc.edu else 118510305Snilay@cs.wisc.edu return new VmlssDFp<float>(machInst, vd, vn, vm, index); 118610305Snilay@cs.wisc.edu case 0x2: 118710305Snilay@cs.wisc.edu if (u) { 118810305Snilay@cs.wisc.edu switch (size) { 118910305Snilay@cs.wisc.edu case 1: 119010305Snilay@cs.wisc.edu return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 11917839Snilay@cs.wisc.edu case 2: 11927839Snilay@cs.wisc.edu return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 11938337Snilay@cs.wisc.edu default: 11948341Snilay@cs.wisc.edu return new Unknown(machInst); 11957839Snilay@cs.wisc.edu } 11968337Snilay@cs.wisc.edu } else { 11978341Snilay@cs.wisc.edu switch (size) { 11987839Snilay@cs.wisc.edu case 1: 11998337Snilay@cs.wisc.edu return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 12008341Snilay@cs.wisc.edu case 2: 12017839Snilay@cs.wisc.edu return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 12028337Snilay@cs.wisc.edu default: 12038341Snilay@cs.wisc.edu return new Unknown(machInst); 12047839Snilay@cs.wisc.edu } 12057839Snilay@cs.wisc.edu } 120610305Snilay@cs.wisc.edu case 0x6: 120711025Snilay@cs.wisc.edu if (u) { 120810305Snilay@cs.wisc.edu switch (size) { 120910305Snilay@cs.wisc.edu case 1: 121010305Snilay@cs.wisc.edu return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 121110305Snilay@cs.wisc.edu case 2: 121210305Snilay@cs.wisc.edu return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 121310305Snilay@cs.wisc.edu default: 121410305Snilay@cs.wisc.edu return new Unknown(machInst); 121511025Snilay@cs.wisc.edu } 121610305Snilay@cs.wisc.edu } else { 121710305Snilay@cs.wisc.edu switch (size) { 121810305Snilay@cs.wisc.edu case 1: 121910305Snilay@cs.wisc.edu return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 122010305Snilay@cs.wisc.edu case 2: 122110305Snilay@cs.wisc.edu return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 12226657Snate@binkert.org default: 122310305Snilay@cs.wisc.edu return new Unknown(machInst); 122410305Snilay@cs.wisc.edu } 122510305Snilay@cs.wisc.edu } 122610305Snilay@cs.wisc.edu case 0x3: 12276657Snate@binkert.org if (u) { 12286657Snate@binkert.org return new Unknown(machInst); 12297007Snate@binkert.org } else { 12307007Snate@binkert.org switch (size) { 12317007Snate@binkert.org case 1: 12327007Snate@binkert.org return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 12337839Snilay@cs.wisc.edu case 2: 12347839Snilay@cs.wisc.edu return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 12357839Snilay@cs.wisc.edu default: 12367839Snilay@cs.wisc.edu return new Unknown(machInst); 12377839Snilay@cs.wisc.edu } 12387839Snilay@cs.wisc.edu } 12397839Snilay@cs.wisc.edu case 0x7: 12407839Snilay@cs.wisc.edu if (u) { 12417839Snilay@cs.wisc.edu return new Unknown(machInst); 12427839Snilay@cs.wisc.edu } else { 12437839Snilay@cs.wisc.edu switch (size) { 124411025Snilay@cs.wisc.edu case 1: 12456657Snate@binkert.org return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 12466657Snate@binkert.org case 2: 12476657Snate@binkert.org return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 12486657Snate@binkert.org default: 12496657Snate@binkert.org return new Unknown(machInst); 12506657Snate@binkert.org } 12516657Snate@binkert.org } 12526657Snate@binkert.org case 0x8: 12536657Snate@binkert.org if (u) { 12546657Snate@binkert.org switch (size) { 12556657Snate@binkert.org case 1: 12566999Snate@binkert.org return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 12576657Snate@binkert.org case 2: 12586657Snate@binkert.org return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index); 125910964Sdavid.hashe@amd.com default: 126010964Sdavid.hashe@amd.com return new Unknown(machInst); 126110964Sdavid.hashe@amd.com } 126210964Sdavid.hashe@amd.com } else { 126310964Sdavid.hashe@amd.com switch (size) { 126410964Sdavid.hashe@amd.com case 1: 126510964Sdavid.hashe@amd.com return new VmulsD<uint16_t>(machInst, vd, vn, vm, index); 126610964Sdavid.hashe@amd.com case 2: 126710964Sdavid.hashe@amd.com return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 126810964Sdavid.hashe@amd.com default: 126910964Sdavid.hashe@amd.com return new Unknown(machInst); 12706657Snate@binkert.org } 12716657Snate@binkert.org } 12729104Shestness@cs.utexas.edu case 0x9: 12736657Snate@binkert.org if (u) 12746657Snate@binkert.org return new VmulsQFp<float>(machInst, vd, vn, vm, index); 12756657Snate@binkert.org else 12766657Snate@binkert.org return new VmulsDFp<float>(machInst, vd, vn, vm, index); 12776657Snate@binkert.org case 0xa: 127810228Snilay@cs.wisc.edu if (u) { 127911111Snilay@cs.wisc.edu switch (size) { 12806657Snate@binkert.org case 1: 12816657Snate@binkert.org return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 12826657Snate@binkert.org case 2: 12836657Snate@binkert.org return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 12849105SBrad.Beckmann@amd.com default: 12859105SBrad.Beckmann@amd.com return new Unknown(machInst); 12869105SBrad.Beckmann@amd.com } 12879105SBrad.Beckmann@amd.com } else { 12889105SBrad.Beckmann@amd.com switch (size) { 12899105SBrad.Beckmann@amd.com case 1: 12909105SBrad.Beckmann@amd.com return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 12919105SBrad.Beckmann@amd.com case 2: 12926657Snate@binkert.org return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 12936657Snate@binkert.org default: 12946657Snate@binkert.org return new Unknown(machInst); 12956657Snate@binkert.org } 12966657Snate@binkert.org } 12976657Snate@binkert.org case 0xb: 12986657Snate@binkert.org if (u) { 12999104Shestness@cs.utexas.edu return new Unknown(machInst); 13009104Shestness@cs.utexas.edu } else { 13019104Shestness@cs.utexas.edu if (u) { 13029104Shestness@cs.utexas.edu switch (size) { 13036657Snate@binkert.org case 1: 13046657Snate@binkert.org return new Vqdmulls<uint16_t>( 13056657Snate@binkert.org machInst, vd, vn, vm, index); 13066657Snate@binkert.org case 2: 13076657Snate@binkert.org return new Vqdmulls<uint32_t>( 13086657Snate@binkert.org machInst, vd, vn, vm, index); 13096657Snate@binkert.org default: 13106657Snate@binkert.org return new Unknown(machInst); 13116657Snate@binkert.org } 13126657Snate@binkert.org } else { 13137839Snilay@cs.wisc.edu switch (size) { 13147839Snilay@cs.wisc.edu case 1: 13157839Snilay@cs.wisc.edu return new Vqdmulls<int16_t>( 13167839Snilay@cs.wisc.edu machInst, vd, vn, vm, index); 13177839Snilay@cs.wisc.edu case 2: 13187839Snilay@cs.wisc.edu return new Vqdmulls<int32_t>( 13197839Snilay@cs.wisc.edu machInst, vd, vn, vm, index); 13207839Snilay@cs.wisc.edu default: 13217839Snilay@cs.wisc.edu return new Unknown(machInst); 13227839Snilay@cs.wisc.edu } 13237839Snilay@cs.wisc.edu } 13247839Snilay@cs.wisc.edu } 13256657Snate@binkert.org case 0xc: 13266657Snate@binkert.org if (u) { 13276657Snate@binkert.org switch (size) { 13286657Snate@binkert.org case 1: 13296657Snate@binkert.org return new VqdmulhsQ<int16_t>( 13306657Snate@binkert.org machInst, vd, vn, vm, index); 13316657Snate@binkert.org case 2: 13326657Snate@binkert.org return new VqdmulhsQ<int32_t>( 13336657Snate@binkert.org machInst, vd, vn, vm, index); 13346657Snate@binkert.org default: 13356657Snate@binkert.org return new Unknown(machInst); 13366657Snate@binkert.org } 13376657Snate@binkert.org } else { 13386657Snate@binkert.org switch (size) { 13396657Snate@binkert.org case 1: 13406657Snate@binkert.org return new VqdmulhsD<int16_t>( 13416657Snate@binkert.org machInst, vd, vn, vm, index); 134210305Snilay@cs.wisc.edu case 2: 13436657Snate@binkert.org return new VqdmulhsD<int32_t>( 13446657Snate@binkert.org machInst, vd, vn, vm, index); 13456657Snate@binkert.org default: 134610962SBrad.Beckmann@amd.com return new Unknown(machInst); 13478159SBrad.Beckmann@amd.com } 13489465Snilay@cs.wisc.edu } 13496657Snate@binkert.org case 0xd: 135010305Snilay@cs.wisc.edu if (u) { 13516657Snate@binkert.org switch (size) { 13526657Snate@binkert.org case 1: 13536657Snate@binkert.org return new VqrdmulhsQ<int16_t>( 13546657Snate@binkert.org machInst, vd, vn, vm, index); 13556657Snate@binkert.org case 2: 13566657Snate@binkert.org return new VqrdmulhsQ<int32_t>( 13576657Snate@binkert.org machInst, vd, vn, vm, index); 13586657Snate@binkert.org default: 13596657Snate@binkert.org return new Unknown(machInst); 13607007Snate@binkert.org } 13616999Snate@binkert.org } else { 13627007Snate@binkert.org switch (size) { 13637007Snate@binkert.org case 1: 13647007Snate@binkert.org return new VqrdmulhsD<int16_t>( 13657007Snate@binkert.org machInst, vd, vn, vm, index); 13667007Snate@binkert.org case 2: 13677007Snate@binkert.org return new VqrdmulhsD<int32_t>( 13686657Snate@binkert.org machInst, vd, vn, vm, index); 13696657Snate@binkert.org default: 13706657Snate@binkert.org return new Unknown(machInst); 13716657Snate@binkert.org } 13726657Snate@binkert.org } 13736657Snate@binkert.org } 13746657Snate@binkert.org return new Unknown(machInst); 13756657Snate@binkert.org } 13766657Snate@binkert.org 13776657Snate@binkert.org static StaticInstPtr 13786657Snate@binkert.org decodeNeonTwoRegMisc(ExtMachInst machInst) 13796657Snate@binkert.org { 13806657Snate@binkert.org const uint32_t a = bits(machInst, 17, 16); 13816657Snate@binkert.org const uint32_t b = bits(machInst, 10, 6); 13826657Snate@binkert.org const bool q = bits(machInst, 6); 13836657Snate@binkert.org const IntRegIndex vd = 13846657Snate@binkert.org (IntRegIndex)(2 * (bits(machInst, 15, 12) | 13856657Snate@binkert.org (bits(machInst, 22) << 4))); 13866657Snate@binkert.org const IntRegIndex vm = 13876657Snate@binkert.org (IntRegIndex)(2 * (bits(machInst, 3, 0) | 13886657Snate@binkert.org (bits(machInst, 5) << 4))); 13896657Snate@binkert.org const unsigned size = bits(machInst, 19, 18); 13906657Snate@binkert.org switch (a) { 13916657Snate@binkert.org case 0x0: 13926657Snate@binkert.org switch (bits(b, 4, 1)) { 13936657Snate@binkert.org case 0x0: 13946657Snate@binkert.org switch (size) { 13956657Snate@binkert.org case 0: 13966657Snate@binkert.org if (q) { 13976999Snate@binkert.org return new NVrev64Q<uint8_t>(machInst, vd, vm); 13986657Snate@binkert.org } else { 13996657Snate@binkert.org return new NVrev64D<uint8_t>(machInst, vd, vm); 14007007Snate@binkert.org } 14017007Snate@binkert.org case 1: 14026657Snate@binkert.org if (q) { 14036657Snate@binkert.org return new NVrev64Q<uint16_t>(machInst, vd, vm); 14046657Snate@binkert.org } else { 14056657Snate@binkert.org return new NVrev64D<uint16_t>(machInst, vd, vm); 14066657Snate@binkert.org } 14076657Snate@binkert.org case 2: 14086657Snate@binkert.org if (q) { 14096657Snate@binkert.org return new NVrev64Q<uint32_t>(machInst, vd, vm); 14106657Snate@binkert.org } else { 14116657Snate@binkert.org return new NVrev64D<uint32_t>(machInst, vd, vm); 14126657Snate@binkert.org } 14136657Snate@binkert.org default: 14146657Snate@binkert.org return new Unknown(machInst); 14156657Snate@binkert.org } 14166657Snate@binkert.org case 0x1: 14176657Snate@binkert.org switch (size) { 14186657Snate@binkert.org case 0: 14196657Snate@binkert.org if (q) { 14206657Snate@binkert.org return new NVrev32Q<uint8_t>(machInst, vd, vm); 14216657Snate@binkert.org } else { 14226657Snate@binkert.org return new NVrev32D<uint8_t>(machInst, vd, vm); 14236657Snate@binkert.org } 14246657Snate@binkert.org case 1: 14256657Snate@binkert.org if (q) { 14266657Snate@binkert.org return new NVrev32Q<uint16_t>(machInst, vd, vm); 14276657Snate@binkert.org } else { 14286657Snate@binkert.org return new NVrev32D<uint16_t>(machInst, vd, vm); 14296657Snate@binkert.org } 14306657Snate@binkert.org default: 14316657Snate@binkert.org return new Unknown(machInst); 14326657Snate@binkert.org } 14336657Snate@binkert.org case 0x2: 14346657Snate@binkert.org if (size != 0) { 14356657Snate@binkert.org return new Unknown(machInst); 14366657Snate@binkert.org } else if (q) { 14376657Snate@binkert.org return new NVrev16Q<uint8_t>(machInst, vd, vm); 14386657Snate@binkert.org } else { 14396657Snate@binkert.org return new NVrev16D<uint8_t>(machInst, vd, vm); 14406657Snate@binkert.org } 14416657Snate@binkert.org case 0x4: 14426657Snate@binkert.org return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 14436657Snate@binkert.org q, size, machInst, vd, vm); 14446657Snate@binkert.org case 0x5: 14456657Snate@binkert.org return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 14466657Snate@binkert.org q, size, machInst, vd, vm); 14476657Snate@binkert.org case 0x8: 14486657Snate@binkert.org return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 14496657Snate@binkert.org q, size, machInst, vd, vm); 14506657Snate@binkert.org case 0x9: 14516657Snate@binkert.org return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 14526657Snate@binkert.org q, size, machInst, vd, vm); 14536657Snate@binkert.org case 0xa: 14546657Snate@binkert.org return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 14556657Snate@binkert.org q, size, machInst, vd, vm); 14566657Snate@binkert.org case 0xb: 14576657Snate@binkert.org if (q) 14586657Snate@binkert.org return new NVmvnQ<uint64_t>(machInst, vd, vm); 14596657Snate@binkert.org else 14606657Snate@binkert.org return new NVmvnD<uint64_t>(machInst, vd, vm); 14616657Snate@binkert.org case 0xc: 14626657Snate@binkert.org return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 14636657Snate@binkert.org q, size, machInst, vd, vm); 14646657Snate@binkert.org case 0xd: 14656657Snate@binkert.org return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 14666657Snate@binkert.org q, size, machInst, vd, vm); 14676657Snate@binkert.org case 0xe: 14686657Snate@binkert.org return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 14696657Snate@binkert.org q, size, machInst, vd, vm); 14706657Snate@binkert.org case 0xf: 14716657Snate@binkert.org return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 14726657Snate@binkert.org q, size, machInst, vd, vm); 14736657Snate@binkert.org default: 14746657Snate@binkert.org return new Unknown(machInst); 14756657Snate@binkert.org } 14766657Snate@binkert.org case 0x1: 14776657Snate@binkert.org switch (bits(b, 3, 1)) { 14786657Snate@binkert.org case 0x0: 14796657Snate@binkert.org if (bits(b, 4)) { 14806657Snate@binkert.org if (q) { 14816657Snate@binkert.org return new NVcgtQFp<float>(machInst, vd, vm); 14826657Snate@binkert.org } else { 14836657Snate@binkert.org return new NVcgtDFp<float>(machInst, vd, vm); 14846657Snate@binkert.org } 14856657Snate@binkert.org } else { 14866657Snate@binkert.org return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 14876657Snate@binkert.org q, size, machInst, vd, vm); 14886657Snate@binkert.org } 14896657Snate@binkert.org case 0x1: 14907007Snate@binkert.org if (bits(b, 4)) { 14916657Snate@binkert.org if (q) { 14926657Snate@binkert.org return new NVcgeQFp<float>(machInst, vd, vm); 14936657Snate@binkert.org } else { 14946657Snate@binkert.org return new NVcgeDFp<float>(machInst, vd, vm); 14956657Snate@binkert.org } 14966657Snate@binkert.org } else { 14976657Snate@binkert.org return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 14987007Snate@binkert.org q, size, machInst, vd, vm); 14996657Snate@binkert.org } 15006657Snate@binkert.org case 0x2: 15016657Snate@binkert.org if (bits(b, 4)) { 15026657Snate@binkert.org if (q) { 15036657Snate@binkert.org return new NVceqQFp<float>(machInst, vd, vm); 15046657Snate@binkert.org } else { 15056657Snate@binkert.org return new NVceqDFp<float>(machInst, vd, vm); 15066657Snate@binkert.org } 15076657Snate@binkert.org } else { 15086657Snate@binkert.org return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 15096657Snate@binkert.org q, size, machInst, vd, vm); 15106657Snate@binkert.org } 15116657Snate@binkert.org case 0x3: 15126657Snate@binkert.org if (bits(b, 4)) { 15136657Snate@binkert.org if (q) { 151410917Sbrandon.potter@amd.com return new NVcleQFp<float>(machInst, vd, vm); 15156657Snate@binkert.org } else { 15166657Snate@binkert.org return new NVcleDFp<float>(machInst, vd, vm); 15176657Snate@binkert.org } 15186657Snate@binkert.org } else { 15196657Snate@binkert.org return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 15206657Snate@binkert.org q, size, machInst, vd, vm); 15216657Snate@binkert.org } 15226657Snate@binkert.org case 0x4: 15236657Snate@binkert.org if (bits(b, 4)) { 15246657Snate@binkert.org if (q) { 15256657Snate@binkert.org return new NVcltQFp<float>(machInst, vd, vm); 15266657Snate@binkert.org } else { 15276657Snate@binkert.org return new NVcltDFp<float>(machInst, vd, vm); 15286657Snate@binkert.org } 15296657Snate@binkert.org } else { 15306657Snate@binkert.org return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 15316657Snate@binkert.org q, size, machInst, vd, vm); 15326657Snate@binkert.org } 15336657Snate@binkert.org case 0x6: 15346657Snate@binkert.org if (bits(machInst, 10)) { 15356657Snate@binkert.org if (q) 15366657Snate@binkert.org 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 // Determine if this is backported aarch64 FP instruction 1954 const bool b31_b24 = bits(machInst, 31, 24) == 0xFE; 1955 const bool b23 = bits(machInst, 23); 1956 const bool b21_b18 = bits(machInst, 21, 18) == 0xE; 1957 const bool b11_b9 = bits(machInst, 11, 9) == 0x5; 1958 const bool sz = bits(machInst, 8); 1959 const bool b7_b6 = bits(machInst, 7, 6) == 0x1; 1960 const bool b6 = bits(machInst, 6) == 0x0; 1961 const bool b4 = bits(machInst, 4) == 0x0; 1962 if (b31_b24 && b23 && b21_b18 && b11_b9 && b7_b6 && b4) { 1963 // VINT* Integer Rounding Instructon 1964 const uint32_t rm = bits(machInst, 17, 16); 1965 1966 if (sz) { 1967 const IntRegIndex vd = 1968 (IntRegIndex)((bits(machInst, 22) << 5) | 1969 (bits(machInst, 15, 12) << 1)); 1970 const IntRegIndex vm = 1971 (IntRegIndex)((bits(machInst, 5) << 5) | 1972 (bits(machInst, 3, 0) << 1)); 1973 switch(rm) { 1974 case 0x0: 1975 return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm, 1976 true); 1977 case 0x1: 1978 return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm, 1979 true); 1980 case 0x2: 1981 return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm, 1982 true); 1983 case 0x3: 1984 return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm, 1985 true); 1986 default: return new Unknown(machInst); 1987 } 1988 } else { 1989 const IntRegIndex vd = 1990 (IntRegIndex)(bits(machInst, 22) | 1991 (bits(machInst, 15, 12) << 1)); 1992 const IntRegIndex vm = 1993 (IntRegIndex)(bits(machInst, 5) | 1994 (bits(machInst, 3, 0) << 1)); 1995 switch(rm) { 1996 case 0x0: 1997 return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm, 1998 false); 1999 case 0x1: 2000 return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm, 2001 false); 2002 case 0x2: 2003 return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm, 2004 false); 2005 case 0x3: 2006 return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm, 2007 false); 2008 default: return new Unknown(machInst); 2009 } 2010 } 2011 } else if (b31_b24 && !b23 && b11_b9 && b6 && b4){ 2012 // VSEL* floating point conditional select 2013 2014 ConditionCode cond; 2015 switch(bits(machInst, 21, 20)) { 2016 case 0x0: cond = COND_EQ; break; 2017 case 0x1: cond = COND_VS; break; 2018 case 0x2: cond = COND_GE; break; 2019 case 0x3: cond = COND_GT; break; 2020 } 2021 2022 if (sz) { 2023 const IntRegIndex vd = 2024 (IntRegIndex)((bits(machInst, 22) << 5) | 2025 (bits(machInst, 15, 12) << 1)); 2026 const IntRegIndex vm = 2027 (IntRegIndex)((bits(machInst, 5) << 5) | 2028 (bits(machInst, 3, 0) << 1)); 2029 const IntRegIndex vn = 2030 (IntRegIndex)((bits(machInst, 7) << 5) | 2031 (bits(machInst, 19, 16) << 1)); 2032 return new VselD(machInst, vd, vn, vm, cond); 2033 } else { 2034 const IntRegIndex vd = 2035 (IntRegIndex)(bits(machInst, 22) | 2036 (bits(machInst, 15, 12) << 1)); 2037 const IntRegIndex vm = 2038 (IntRegIndex)(bits(machInst, 5) | 2039 (bits(machInst, 3, 0) << 1)); 2040 const IntRegIndex vn = 2041 (IntRegIndex)((bits(machInst, 19, 16) << 1) | 2042 bits(machInst, 7)); 2043 return new VselS(machInst, vd, vn, vm, cond); 2044 } 2045 } else { 2046 return new Unknown(machInst); 2047 } 2048 } 2049 if (l == 0 && c == 0) { 2050 if (a == 0) { 2051 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2052 bits(machInst, 7); 2053 const IntRegIndex rt = 2054 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2055 if (bits(machInst, 20) == 1) { 2056 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2057 } else { 2058 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2059 } 2060 } else if (a == 0x7) { 2061 const IntRegIndex rt = 2062 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2063 uint32_t reg = bits(machInst, 19, 16); 2064 uint32_t specReg; 2065 switch (reg) { 2066 case 0: 2067 specReg = MISCREG_FPSID; 2068 break; 2069 case 1: 2070 specReg = MISCREG_FPSCR; 2071 break; 2072 case 6: 2073 specReg = MISCREG_MVFR1; 2074 break; 2075 case 7: 2076 specReg = MISCREG_MVFR0; 2077 break; 2078 case 8: 2079 specReg = MISCREG_FPEXC; 2080 break; 2081 default: 2082 return new Unknown(machInst); 2083 } 2084 if (specReg == MISCREG_FPSCR) { 2085 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 2086 } else { 2087 uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt, 2088 reg, a, bits(machInst, 7, 5)); 2089 return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss); 2090 } 2091 } 2092 } else if (l == 0 && c == 1) { 2093 if (bits(a, 2) == 0) { 2094 uint32_t vd = (bits(machInst, 7) << 5) | 2095 (bits(machInst, 19, 16) << 1); 2096 // Handle accessing each single precision half of the vector. 2097 vd += bits(machInst, 21); 2098 const IntRegIndex rt = 2099 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2100 if (bits(machInst, 22) == 1) { 2101 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 2102 rt, bits(machInst, 6, 5)); 2103 } else if (bits(machInst, 5) == 1) { 2104 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 2105 rt, bits(machInst, 6)); 2106 } else if (bits(machInst, 6) == 0) { 2107 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 2108 } else { 2109 return new Unknown(machInst); 2110 } 2111 } else if (bits(b, 1) == 0) { 2112 bool q = bits(machInst, 21); 2113 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2114 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2115 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2116 IntRegIndex rt = (IntRegIndex)(uint32_t) 2117 bits(machInst, 15, 12); 2118 if (q) { 2119 switch (be) { 2120 case 0: 2121 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2122 case 1: 2123 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2124 case 2: 2125 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2126 case 3: 2127 return new Unknown(machInst); 2128 } 2129 } else { 2130 switch (be) { 2131 case 0: 2132 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2133 case 1: 2134 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2135 case 2: 2136 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2137 case 3: 2138 return new Unknown(machInst); 2139 } 2140 } 2141 } 2142 } else if (l == 1 && c == 0) { 2143 if (a == 0) { 2144 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2145 bits(machInst, 7); 2146 const IntRegIndex rt = 2147 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2148 if (bits(machInst, 20) == 1) { 2149 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2150 } else { 2151 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2152 } 2153 } else if (a == 7) { 2154 const IntRegIndex rt = 2155 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2156 uint32_t reg = bits(machInst, 19, 16); 2157 uint32_t specReg; 2158 switch (reg) { 2159 case 0: 2160 specReg = MISCREG_FPSID; 2161 break; 2162 case 1: 2163 specReg = MISCREG_FPSCR; 2164 break; 2165 case 6: 2166 specReg = MISCREG_MVFR1; 2167 break; 2168 case 7: 2169 specReg = MISCREG_MVFR0; 2170 break; 2171 case 8: 2172 specReg = MISCREG_FPEXC; 2173 break; 2174 default: 2175 return new Unknown(machInst); 2176 } 2177 if (rt == 0xf) { 2178 if (specReg == MISCREG_FPSCR) { 2179 return new VmrsApsrFpscr(machInst); 2180 } else { 2181 return new Unknown(machInst); 2182 } 2183 } else if (specReg == MISCREG_FPSCR) { 2184 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2185 } else { 2186 uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt, 2187 reg, a, bits(machInst, 7, 5)); 2188 return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss); 2189 } 2190 } 2191 } else { 2192 uint32_t vd = (bits(machInst, 7) << 5) | 2193 (bits(machInst, 19, 16) << 1); 2194 // Handle indexing into each single precision half of the vector. 2195 vd += bits(machInst, 21); 2196 uint32_t index; 2197 const IntRegIndex rt = 2198 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2199 const bool u = (bits(machInst, 23) == 1); 2200 if (bits(machInst, 22) == 1) { 2201 index = bits(machInst, 6, 5); 2202 if (u) { 2203 return new VmovRegCoreUB(machInst, rt, 2204 (IntRegIndex)vd, index); 2205 } else { 2206 return new VmovRegCoreSB(machInst, rt, 2207 (IntRegIndex)vd, index); 2208 } 2209 } else if (bits(machInst, 5) == 1) { 2210 index = bits(machInst, 6); 2211 if (u) { 2212 return new VmovRegCoreUH(machInst, rt, 2213 (IntRegIndex)vd, index); 2214 } else { 2215 return new VmovRegCoreSH(machInst, rt, 2216 (IntRegIndex)vd, index); 2217 } 2218 } else if (bits(machInst, 6) == 0 && !u) { 2219 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2220 } else { 2221 return new Unknown(machInst); 2222 } 2223 } 2224 return new Unknown(machInst); 2225 } 2226 ''' 2227}}; 2228 2229def format ShortFpTransfer() {{ 2230 decode_block = ''' 2231 return decodeShortFpTransfer(machInst); 2232 ''' 2233}}; 2234 2235let {{ 2236 header_output = ''' 2237 StaticInstPtr 2238 decodeVfpData(ExtMachInst machInst); 2239 ''' 2240 decoder_output = ''' 2241 StaticInstPtr 2242 decodeVfpData(ExtMachInst machInst) 2243 { 2244 const uint32_t opc1 = bits(machInst, 23, 20); 2245 const uint32_t opc2 = bits(machInst, 19, 16); 2246 const uint32_t opc3 = bits(machInst, 7, 6); 2247 //const uint32_t opc4 = bits(machInst, 3, 0); 2248 const bool single = (bits(machInst, 8) == 0); 2249 // Used to select between vcmp and vcmpe. 2250 const bool e = (bits(machInst, 7) == 1); 2251 IntRegIndex vd; 2252 IntRegIndex vm; 2253 IntRegIndex vn; 2254 if (single) { 2255 vd = (IntRegIndex)(bits(machInst, 22) | 2256 (bits(machInst, 15, 12) << 1)); 2257 vm = (IntRegIndex)(bits(machInst, 5) | 2258 (bits(machInst, 3, 0) << 1)); 2259 vn = (IntRegIndex)(bits(machInst, 7) | 2260 (bits(machInst, 19, 16) << 1)); 2261 } else { 2262 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2263 (bits(machInst, 15, 12) << 1)); 2264 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2265 (bits(machInst, 3, 0) << 1)); 2266 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2267 (bits(machInst, 19, 16) << 1)); 2268 } 2269 switch (opc1 & 0xb /* 1011 */) { 2270 case 0x0: 2271 if (bits(machInst, 6) == 0) { 2272 if (single) { 2273 return decodeVfpRegRegRegOp<VmlaS>( 2274 machInst, vd, vn, vm, false); 2275 } else { 2276 return decodeVfpRegRegRegOp<VmlaD>( 2277 machInst, vd, vn, vm, true); 2278 } 2279 } else { 2280 if (single) { 2281 return decodeVfpRegRegRegOp<VmlsS>( 2282 machInst, vd, vn, vm, false); 2283 } else { 2284 return decodeVfpRegRegRegOp<VmlsD>( 2285 machInst, vd, vn, vm, true); 2286 } 2287 } 2288 case 0x1: 2289 if (bits(machInst, 6) == 1) { 2290 if (single) { 2291 return decodeVfpRegRegRegOp<VnmlaS>( 2292 machInst, vd, vn, vm, false); 2293 } else { 2294 return decodeVfpRegRegRegOp<VnmlaD>( 2295 machInst, vd, vn, vm, true); 2296 } 2297 } else { 2298 if (single) { 2299 return decodeVfpRegRegRegOp<VnmlsS>( 2300 machInst, vd, vn, vm, false); 2301 } else { 2302 return decodeVfpRegRegRegOp<VnmlsD>( 2303 machInst, vd, vn, vm, true); 2304 } 2305 } 2306 case 0x2: 2307 if ((opc3 & 0x1) == 0) { 2308 if (single) { 2309 return decodeVfpRegRegRegOp<VmulS>( 2310 machInst, vd, vn, vm, false); 2311 } else { 2312 return decodeVfpRegRegRegOp<VmulD>( 2313 machInst, vd, vn, vm, true); 2314 } 2315 } else { 2316 if (single) { 2317 return decodeVfpRegRegRegOp<VnmulS>( 2318 machInst, vd, vn, vm, false); 2319 } else { 2320 return decodeVfpRegRegRegOp<VnmulD>( 2321 machInst, vd, vn, vm, true); 2322 } 2323 } 2324 case 0x3: 2325 if ((opc3 & 0x1) == 0) { 2326 if (single) { 2327 return decodeVfpRegRegRegOp<VaddS>( 2328 machInst, vd, vn, vm, false); 2329 } else { 2330 return decodeVfpRegRegRegOp<VaddD>( 2331 machInst, vd, vn, vm, true); 2332 } 2333 } else { 2334 if (single) { 2335 return decodeVfpRegRegRegOp<VsubS>( 2336 machInst, vd, vn, vm, false); 2337 } else { 2338 return decodeVfpRegRegRegOp<VsubD>( 2339 machInst, vd, vn, vm, true); 2340 } 2341 } 2342 case 0x8: 2343 if ((opc3 & 0x1) == 0) { 2344 if (single) { 2345 return decodeVfpRegRegRegOp<VdivS>( 2346 machInst, vd, vn, vm, false); 2347 } else { 2348 return decodeVfpRegRegRegOp<VdivD>( 2349 machInst, vd, vn, vm, true); 2350 } 2351 } 2352 break; 2353 case 0x9: 2354 if ((opc3 & 0x1) == 0) { 2355 if (single) { 2356 return decodeVfpRegRegRegOp<VfnmaS>( 2357 machInst, vd, vn, vm, false); 2358 } else { 2359 return decodeVfpRegRegRegOp<VfnmaD>( 2360 machInst, vd, vn, vm, true); 2361 } 2362 } else { 2363 if (single) { 2364 return decodeVfpRegRegRegOp<VfnmsS>( 2365 machInst, vd, vn, vm, false); 2366 } else { 2367 return decodeVfpRegRegRegOp<VfnmsD>( 2368 machInst, vd, vn, vm, true); 2369 } 2370 } 2371 break; 2372 case 0xa: 2373 if ((opc3 & 0x1) == 0) { 2374 if (single) { 2375 return decodeVfpRegRegRegOp<VfmaS>( 2376 machInst, vd, vn, vm, false); 2377 } else { 2378 return decodeVfpRegRegRegOp<VfmaD>( 2379 machInst, vd, vn, vm, true); 2380 } 2381 } else { 2382 if (single) { 2383 return decodeVfpRegRegRegOp<VfmsS>( 2384 machInst, vd, vn, vm, false); 2385 } else { 2386 return decodeVfpRegRegRegOp<VfmsD>( 2387 machInst, vd, vn, vm, true); 2388 } 2389 } 2390 break; 2391 case 0xb: 2392 if ((opc3 & 0x1) == 0) { 2393 const uint32_t baseImm = 2394 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2395 if (single) { 2396 uint32_t imm = vfp_modified_imm(baseImm, false); 2397 return decodeVfpRegImmOp<VmovImmS>( 2398 machInst, vd, imm, false); 2399 } else { 2400 uint64_t imm = vfp_modified_imm(baseImm, true); 2401 return decodeVfpRegImmOp<VmovImmD>( 2402 machInst, vd, imm, true); 2403 } 2404 } 2405 switch (opc2) { 2406 case 0x0: 2407 if (opc3 == 1) { 2408 if (single) { 2409 return decodeVfpRegRegOp<VmovRegS>( 2410 machInst, vd, vm, false); 2411 } else { 2412 return decodeVfpRegRegOp<VmovRegD>( 2413 machInst, vd, vm, true); 2414 } 2415 } else { 2416 if (single) { 2417 return decodeVfpRegRegOp<VabsS>( 2418 machInst, vd, vm, false); 2419 } else { 2420 return decodeVfpRegRegOp<VabsD>( 2421 machInst, vd, vm, true); 2422 } 2423 } 2424 case 0x1: 2425 if (opc3 == 1) { 2426 if (single) { 2427 return decodeVfpRegRegOp<VnegS>( 2428 machInst, vd, vm, false); 2429 } else { 2430 return decodeVfpRegRegOp<VnegD>( 2431 machInst, vd, vm, true); 2432 } 2433 } else { 2434 if (single) { 2435 return decodeVfpRegRegOp<VsqrtS>( 2436 machInst, vd, vm, false); 2437 } else { 2438 return decodeVfpRegRegOp<VsqrtD>( 2439 machInst, vd, vm, true); 2440 } 2441 } 2442 case 0x2: 2443 case 0x3: 2444 { 2445 const bool toHalf = bits(machInst, 16); 2446 const bool top = bits(machInst, 7); 2447 if (top) { 2448 if (toHalf) { 2449 return new VcvtFpSFpHT(machInst, vd, vm); 2450 } else { 2451 return new VcvtFpHTFpS(machInst, vd, vm); 2452 } 2453 } else { 2454 if (toHalf) { 2455 return new VcvtFpSFpHB(machInst, vd, vm); 2456 } else { 2457 return new VcvtFpHBFpS(machInst, vd, vm); 2458 } 2459 } 2460 } 2461 case 0x4: 2462 if (single) { 2463 if (e) { 2464 return new VcmpeS(machInst, vd, vm); 2465 } else { 2466 return new VcmpS(machInst, vd, vm); 2467 } 2468 } else { 2469 if (e) { 2470 return new VcmpeD(machInst, vd, vm); 2471 } else { 2472 return new VcmpD(machInst, vd, vm); 2473 } 2474 } 2475 case 0x5: 2476 if (single) { 2477 if (e) { 2478 return new VcmpeZeroS(machInst, vd, 0); 2479 } else { 2480 return new VcmpZeroS(machInst, vd, 0); 2481 } 2482 } else { 2483 if (e) { 2484 return new VcmpeZeroD(machInst, vd, 0); 2485 } else { 2486 return new VcmpZeroD(machInst, vd, 0); 2487 } 2488 } 2489 case 0x7: 2490 if (opc3 == 0x3) { 2491 if (single) { 2492 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2493 (bits(machInst, 15, 12) << 1)); 2494 return new VcvtFpSFpD(machInst, vd, vm); 2495 } else { 2496 vd = (IntRegIndex)(bits(machInst, 22) | 2497 (bits(machInst, 15, 12) << 1)); 2498 return new VcvtFpDFpS(machInst, vd, vm); 2499 } 2500 } 2501 break; 2502 case 0x8: 2503 if (bits(machInst, 7) == 0) { 2504 if (single) { 2505 return new VcvtUIntFpS(machInst, vd, vm); 2506 } else { 2507 vm = (IntRegIndex)(bits(machInst, 5) | 2508 (bits(machInst, 3, 0) << 1)); 2509 return new VcvtUIntFpD(machInst, vd, vm); 2510 } 2511 } else { 2512 if (single) { 2513 return new VcvtSIntFpS(machInst, vd, vm); 2514 } else { 2515 vm = (IntRegIndex)(bits(machInst, 5) | 2516 (bits(machInst, 3, 0) << 1)); 2517 return new VcvtSIntFpD(machInst, vd, vm); 2518 } 2519 } 2520 case 0xa: 2521 { 2522 const bool half = (bits(machInst, 7) == 0); 2523 const uint32_t imm = bits(machInst, 5) | 2524 (bits(machInst, 3, 0) << 1); 2525 const uint32_t size = 2526 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2527 if (single) { 2528 if (half) { 2529 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2530 } else { 2531 return new VcvtSFixedFpS(machInst, vd, vd, size); 2532 } 2533 } else { 2534 if (half) { 2535 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2536 } else { 2537 return new VcvtSFixedFpD(machInst, vd, vd, size); 2538 } 2539 } 2540 } 2541 case 0xb: 2542 { 2543 const bool half = (bits(machInst, 7) == 0); 2544 const uint32_t imm = bits(machInst, 5) | 2545 (bits(machInst, 3, 0) << 1); 2546 const uint32_t size = 2547 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2548 if (single) { 2549 if (half) { 2550 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2551 } else { 2552 return new VcvtUFixedFpS(machInst, vd, vd, size); 2553 } 2554 } else { 2555 if (half) { 2556 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2557 } else { 2558 return new VcvtUFixedFpD(machInst, vd, vd, size); 2559 } 2560 } 2561 } 2562 case 0xc: 2563 if (bits(machInst, 7) == 0) { 2564 if (single) { 2565 return new VcvtFpUIntSR(machInst, vd, vm); 2566 } else { 2567 vd = (IntRegIndex)(bits(machInst, 22) | 2568 (bits(machInst, 15, 12) << 1)); 2569 return new VcvtFpUIntDR(machInst, vd, vm); 2570 } 2571 } else { 2572 if (single) { 2573 return new VcvtFpUIntS(machInst, vd, vm); 2574 } else { 2575 vd = (IntRegIndex)(bits(machInst, 22) | 2576 (bits(machInst, 15, 12) << 1)); 2577 return new VcvtFpUIntD(machInst, vd, vm); 2578 } 2579 } 2580 case 0xd: 2581 if (bits(machInst, 7) == 0) { 2582 if (single) { 2583 return new VcvtFpSIntSR(machInst, vd, vm); 2584 } else { 2585 vd = (IntRegIndex)(bits(machInst, 22) | 2586 (bits(machInst, 15, 12) << 1)); 2587 return new VcvtFpSIntDR(machInst, vd, vm); 2588 } 2589 } else { 2590 if (single) { 2591 return new VcvtFpSIntS(machInst, vd, vm); 2592 } else { 2593 vd = (IntRegIndex)(bits(machInst, 22) | 2594 (bits(machInst, 15, 12) << 1)); 2595 return new VcvtFpSIntD(machInst, vd, vm); 2596 } 2597 } 2598 case 0xe: 2599 { 2600 const bool half = (bits(machInst, 7) == 0); 2601 const uint32_t imm = bits(machInst, 5) | 2602 (bits(machInst, 3, 0) << 1); 2603 const uint32_t size = 2604 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2605 if (single) { 2606 if (half) { 2607 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2608 } else { 2609 return new VcvtFpSFixedS(machInst, vd, vd, size); 2610 } 2611 } else { 2612 if (half) { 2613 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2614 } else { 2615 return new VcvtFpSFixedD(machInst, vd, vd, size); 2616 } 2617 } 2618 } 2619 case 0xf: 2620 { 2621 const bool half = (bits(machInst, 7) == 0); 2622 const uint32_t imm = bits(machInst, 5) | 2623 (bits(machInst, 3, 0) << 1); 2624 const uint32_t size = 2625 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2626 if (single) { 2627 if (half) { 2628 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2629 } else { 2630 return new VcvtFpUFixedS(machInst, vd, vd, size); 2631 } 2632 } else { 2633 if (half) { 2634 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2635 } else { 2636 return new VcvtFpUFixedD(machInst, vd, vd, size); 2637 } 2638 } 2639 } 2640 } 2641 break; 2642 } 2643 return new Unknown(machInst); 2644 } 2645 ''' 2646}}; 2647 2648def format VfpData() {{ 2649 decode_block = ''' 2650 return decodeVfpData(machInst); 2651 ''' 2652}}; 2653