fp.isa revision 7643:775ccd204013
1360SN/A// -*- mode:c++ -*- 210850SGiacomo.Gabrielli@arm.com 310796Sbrandon.potter@amd.com// Copyright (c) 2010 ARM Limited 410027SChris.Adeniyi-Jones@arm.com// All rights reserved 510027SChris.Adeniyi-Jones@arm.com// 610027SChris.Adeniyi-Jones@arm.com// The license below extends only to copyright in the software and shall 710027SChris.Adeniyi-Jones@arm.com// not be construed as granting a license to any other intellectual 810027SChris.Adeniyi-Jones@arm.com// property including but not limited to intellectual property relating 910027SChris.Adeniyi-Jones@arm.com// to a hardware implementation of the functionality of the software 1010027SChris.Adeniyi-Jones@arm.com// licensed hereunder. You may use the software subject to the license 1110027SChris.Adeniyi-Jones@arm.com// terms below provided that you ensure that this notice is replicated 1210027SChris.Adeniyi-Jones@arm.com// unmodified and in its entirety in all distributions of the software, 1310027SChris.Adeniyi-Jones@arm.com// modified or unmodified, in source code or in binary form. 1410027SChris.Adeniyi-Jones@arm.com// 151458SN/A// Copyright (c) 2007-2008 The Florida State University 16360SN/A// All rights reserved. 17360SN/A// 18360SN/A// Redistribution and use in source and binary forms, with or without 19360SN/A// modification, are permitted provided that the following conditions are 20360SN/A// met: redistributions of source code must retain the above copyright 21360SN/A// notice, this list of conditions and the following disclaimer; 22360SN/A// redistributions in binary form must reproduce the above copyright 23360SN/A// notice, this list of conditions and the following disclaimer in the 24360SN/A// documentation and/or other materials provided with the distribution; 25360SN/A// neither the name of the copyright holders nor the names of its 26360SN/A// contributors may be used to endorse or promote products derived from 27360SN/A// this software without specific prior written permission. 28360SN/A// 29360SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30360SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31360SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32360SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33360SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34360SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35360SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36360SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37360SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38360SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39360SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu// 412665Ssaidi@eecs.umich.edu// Authors: Stephen Hines 422665Ssaidi@eecs.umich.edu 43360SN/A//////////////////////////////////////////////////////////////////// 44360SN/A// 451354SN/A// Floating Point operate instructions 461354SN/A// 47360SN/A 482764Sstever@eecs.umich.eduoutput header {{ 499202Spalle@lyckegaard.dk 509202Spalle@lyckegaard.dk template<template <typename T> class Base> 512064SN/A StaticInstPtr 52360SN/A newNeonMemInst(const unsigned size, 53360SN/A const ExtMachInst &machInst, 54360SN/A const RegIndex dest, const RegIndex ra, 55360SN/A const uint32_t imm, const unsigned extraMemFlags) 56360SN/A { 57360SN/A switch (size) { 581809SN/A case 0: 595543Ssaidi@eecs.umich.edu return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags); 6011392Sbrandon.potter@amd.com case 1: 611809SN/A return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags); 6211392Sbrandon.potter@amd.com case 2: 6311383Sbrandon.potter@amd.com return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags); 643113Sgblack@eecs.umich.edu case 3: 658229Snate@binkert.org return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags); 668229Snate@binkert.org default: 6711594Santhony.gutierrez@amd.com panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 687075Snate@binkert.org } 698229Snate@binkert.org } 707075Snate@binkert.org 71360SN/A template<template <typename T> class Base> 722474SN/A StaticInstPtr 735543Ssaidi@eecs.umich.edu newNeonMixInst(const unsigned size, 7411392Sbrandon.potter@amd.com const ExtMachInst &machInst, 752462SN/A const RegIndex dest, const RegIndex op1, 761354SN/A const uint32_t step) 776216Snate@binkert.org { 786658Snate@binkert.org switch (size) { 792474SN/A case 0: 802680Sktlim@umich.edu return new Base<uint8_t>(machInst, dest, op1, step); 8111380Salexandru.dutu@amd.com case 1: 828232Snate@binkert.org return new Base<uint16_t>(machInst, dest, op1, step); 838229Snate@binkert.org case 2: 847678Sgblack@eecs.umich.edu return new Base<uint32_t>(machInst, dest, op1, step); 8510496Ssteve.reinhardt@amd.com case 3: 868229Snate@binkert.org return new Base<uint64_t>(machInst, dest, op1, step); 8710497Ssteve.reinhardt@amd.com default: 888766Sgblack@eecs.umich.edu panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 896640Svince@csl.cornell.edu } 90360SN/A } 9111380Salexandru.dutu@amd.com 9211380Salexandru.dutu@amd.com}}; 9311380Salexandru.dutu@amd.com 9411380Salexandru.dutu@amd.comlet {{ 9511380Salexandru.dutu@amd.com header_output = ''' 9611380Salexandru.dutu@amd.com StaticInstPtr 9711380Salexandru.dutu@amd.com decodeNeonMem(ExtMachInst machInst); 9811380Salexandru.dutu@amd.com 99360SN/A StaticInstPtr 100360SN/A decodeNeonData(ExtMachInst machInst); 101360SN/A ''' 102360SN/A 103360SN/A decoder_output = ''' 104360SN/A StaticInstPtr 105360SN/A decodeNeonMem(ExtMachInst machInst) 106378SN/A { 1071450SN/A const uint32_t b = bits(machInst, 11, 8); 1083114Sgblack@eecs.umich.edu const bool single = bits(machInst, 23); 109360SN/A const bool singleAll = single && (bits(b, 3, 2) == 3); 1105543Ssaidi@eecs.umich.edu const bool load = bits(machInst, 21); 1115543Ssaidi@eecs.umich.edu 1125543Ssaidi@eecs.umich.edu unsigned width = 0; 11310831Ssteve.reinhardt@amd.com 114360SN/A if (single) { 115360SN/A width = bits(b, 1, 0) + 1; 116360SN/A } else { 117360SN/A switch (bits(b, 3, 1)) { 118360SN/A case 0x0: width = 4; 1192680Sktlim@umich.edu break; 120360SN/A case 0x1: width = (b & 0x1) ? 2 : 1; 12110831Ssteve.reinhardt@amd.com break; 12210831Ssteve.reinhardt@amd.com case 0x2: width = 3; 123360SN/A break; 124360SN/A case 0x3: width = 1; 125360SN/A break; 126360SN/A case 0x4: width = 2; 12710831Ssteve.reinhardt@amd.com break; 128360SN/A case 0x5: 129360SN/A if ((b & 0x1) == 0) { 130360SN/A width = 1; 131360SN/A break; 1323114Sgblack@eecs.umich.edu } 13310831Ssteve.reinhardt@amd.com // Fall through on purpose. 13410831Ssteve.reinhardt@amd.com default: 13510831Ssteve.reinhardt@amd.com return new Unknown(machInst); 136360SN/A } 137360SN/A } 138360SN/A assert(width > 0 && width <= 4); 139360SN/A 140360SN/A const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0); 141360SN/A const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16); 142360SN/A const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) | 143360SN/A bits(machInst, 22) << 4); 144360SN/A const uint32_t type = bits(machInst, 11, 8); 145360SN/A uint32_t size = 0; 146360SN/A uint32_t align = 0; 147360SN/A unsigned inc = 1; 148378SN/A unsigned regs = 1; 1491706SN/A unsigned lane = 0; 1503114Sgblack@eecs.umich.edu if (single) { 151378SN/A if (singleAll) { 152378SN/A size = bits(machInst, 7, 6); 153378SN/A bool t = bits(machInst, 5); 154378SN/A unsigned eBytes = (1 << size); 155378SN/A align = (eBytes - 1) | TLB::AllowUnaligned; 1561706SN/A if (width == 1) { 1573114Sgblack@eecs.umich.edu regs = t ? 2 : 1; 158360SN/A inc = 1; 1596109Ssanchezd@stanford.edu } else { 1601706SN/A regs = width; 1613114Sgblack@eecs.umich.edu inc = t ? 2 : 1; 162378SN/A } 1636109Ssanchezd@stanford.edu switch (width) { 1646109Ssanchezd@stanford.edu case 1: 1656109Ssanchezd@stanford.edu case 2: 1666109Ssanchezd@stanford.edu if (bits(machInst, 4)) 167378SN/A align = width * eBytes - 1; 1681706SN/A break; 1693114Sgblack@eecs.umich.edu case 3: 170378SN/A break; 1715748SSteve.Reinhardt@amd.com case 4: 1725748SSteve.Reinhardt@amd.com if (size == 3) { 1735748SSteve.Reinhardt@amd.com if (bits(machInst, 4) == 0) 174378SN/A return new Unknown(machInst); 175378SN/A size = 2; 1761706SN/A align = 0xf; 1773114Sgblack@eecs.umich.edu } else if (size == 2) { 178378SN/A if (bits(machInst, 4)) 179378SN/A align = 7; 1801706SN/A } else { 1813114Sgblack@eecs.umich.edu if (bits(machInst, 4)) 182378SN/A align = 4 * eBytes - 1; 183378SN/A } 1841706SN/A break; 1853114Sgblack@eecs.umich.edu } 186378SN/A } else { 187378SN/A size = bits(machInst, 11, 10); 1881706SN/A unsigned eBytes = (1 << size); 1893114Sgblack@eecs.umich.edu align = (eBytes - 1) | TLB::AllowUnaligned; 190378SN/A regs = width; 1914118Sgblack@eecs.umich.edu unsigned indexAlign = bits(machInst, 7, 4); 1924118Sgblack@eecs.umich.edu // If width is 1, inc is always 1. That's overridden later. 1934118Sgblack@eecs.umich.edu switch (size) { 1944118Sgblack@eecs.umich.edu case 0: 195378SN/A inc = 1; 1961706SN/A lane = bits(indexAlign, 3, 1); 1973114Sgblack@eecs.umich.edu break; 198378SN/A case 1: 199378SN/A inc = bits(indexAlign, 1) ? 2 : 1; 2001706SN/A lane = bits(indexAlign, 3, 2); 2013114Sgblack@eecs.umich.edu break; 202360SN/A case 2: 2035513SMichael.Adler@intel.com inc = bits(indexAlign, 2) ? 2 : 1; 2045513SMichael.Adler@intel.com lane = bits(indexAlign, 3); 2055513SMichael.Adler@intel.com break; 2065513SMichael.Adler@intel.com } 20710203SAli.Saidi@ARM.com // Override inc for width of 1. 20810203SAli.Saidi@ARM.com if (width == 1) { 20910203SAli.Saidi@ARM.com inc = 1; 21010203SAli.Saidi@ARM.com } 2115513SMichael.Adler@intel.com switch (width) { 2125513SMichael.Adler@intel.com case 1: 2135513SMichael.Adler@intel.com switch (size) { 214511SN/A case 0: 21510633Smichaelupton@gmail.com break; 21610633Smichaelupton@gmail.com case 1: 21710633Smichaelupton@gmail.com if (bits(indexAlign, 0)) 2181706SN/A align = 1; 2193114Sgblack@eecs.umich.edu break; 220511SN/A case 2: 2215513SMichael.Adler@intel.com if (bits(indexAlign, 1, 0)) 2225513SMichael.Adler@intel.com align = 3; 2235513SMichael.Adler@intel.com break; 2245513SMichael.Adler@intel.com } 225511SN/A break; 2261706SN/A case 2: 2273114Sgblack@eecs.umich.edu if (bits(indexAlign, 0)) 2281706SN/A align = (2 * eBytes) - 1; 2291706SN/A break; 2301706SN/A case 3: 2311706SN/A break; 2323114Sgblack@eecs.umich.edu case 4: 2331706SN/A switch (size) { 2341706SN/A case 0: 2351706SN/A case 1: 2361706SN/A if (bits(indexAlign, 0)) 2373114Sgblack@eecs.umich.edu align = (4 * eBytes) - 1; 2381706SN/A break; 239511SN/A case 2: 2406703Svince@csl.cornell.edu if (bits(indexAlign, 0)) 2416703Svince@csl.cornell.edu align = (4 << bits(indexAlign, 1, 0)) - 1; 2426703Svince@csl.cornell.edu break; 2436703Svince@csl.cornell.edu } 2446685Stjones1@inf.ed.ac.uk break; 2456685Stjones1@inf.ed.ac.uk } 2466685Stjones1@inf.ed.ac.uk } 2476685Stjones1@inf.ed.ac.uk if (size == 0x3) { 2486685Stjones1@inf.ed.ac.uk return new Unknown(machInst); 2495513SMichael.Adler@intel.com } 2505513SMichael.Adler@intel.com } else { 2515513SMichael.Adler@intel.com size = bits(machInst, 7, 6); 2525513SMichael.Adler@intel.com align = bits(machInst, 5, 4); 2535513SMichael.Adler@intel.com if (align == 0) { 2541999SN/A // @align wasn't specified, so alignment can be turned off. 2551999SN/A align = ((1 << size) - 1) | TLB::AllowUnaligned; 2563114Sgblack@eecs.umich.edu } else { 2571999SN/A align = ((4 << align) - 1); 2581999SN/A } 2591999SN/A switch (width) { 2601999SN/A case 1: 2613114Sgblack@eecs.umich.edu switch (type) { 2621999SN/A case 0x7: regs = 1; 2633079Sstever@eecs.umich.edu break; 2643079Sstever@eecs.umich.edu case 0xa: regs = 2; 2653114Sgblack@eecs.umich.edu break; 2663079Sstever@eecs.umich.edu case 0x6: regs = 3; 2672093SN/A break; 2682093SN/A case 0x2: regs = 4; 2693114Sgblack@eecs.umich.edu break; 2702093SN/A default: 2712687Sksewell@umich.edu return new Unknown(machInst); 2722687Sksewell@umich.edu } 2733114Sgblack@eecs.umich.edu break; 2742687Sksewell@umich.edu case 2: 2752238SN/A // Regs doesn't behave exactly as it does in the manual 2762238SN/A // because they loop over regs registers twice and we break 2773114Sgblack@eecs.umich.edu // it down in the macroop. 2782238SN/A switch (type) { 2792238SN/A case 0x8: regs = 2; inc = 1; 2802238SN/A break; 2813114Sgblack@eecs.umich.edu case 0x9: regs = 2; inc = 2; 2822238SN/A break; 2832238SN/A case 0x3: regs = 4; inc = 2; 2842238SN/A break; 2853114Sgblack@eecs.umich.edu default: 2862238SN/A return new Unknown(machInst); 2872238SN/A } 2882238SN/A break; 2893114Sgblack@eecs.umich.edu case 3: 2902238SN/A regs = 3; 2912238SN/A switch (type) { 2922238SN/A case 0x4: inc = 1; 2933114Sgblack@eecs.umich.edu break; 2942238SN/A case 0x5: inc = 2;; 2952238SN/A break; 2962238SN/A default: 2973114Sgblack@eecs.umich.edu return new Unknown(machInst); 2982238SN/A } 2992238SN/A break; 3002238SN/A case 4: 3013114Sgblack@eecs.umich.edu regs = 4; 3022238SN/A switch (type) { 3036109Ssanchezd@stanford.edu case 0: inc = 1; 3046109Ssanchezd@stanford.edu break; 3056109Ssanchezd@stanford.edu case 1: inc = 2; 3062238SN/A break; 3079455Smitch.hayenga+gem5@gmail.com default: 3089455Smitch.hayenga+gem5@gmail.com return new Unknown(machInst); 3099455Smitch.hayenga+gem5@gmail.com } 31010203SAli.Saidi@ARM.com break; 31110203SAli.Saidi@ARM.com } 31210203SAli.Saidi@ARM.com } 3139455Smitch.hayenga+gem5@gmail.com 3149112Smarc.orr@gmail.com if (load) { 3159112Smarc.orr@gmail.com // Load instructions. 3169112Smarc.orr@gmail.com if (single) { 3179112Smarc.orr@gmail.com return new VldSingle(machInst, singleAll, width, rn, vd, 3189112Smarc.orr@gmail.com regs, inc, size, align, rm, lane); 3199112Smarc.orr@gmail.com } else { 3209112Smarc.orr@gmail.com return new VldMult(machInst, width, rn, vd, 3219112Smarc.orr@gmail.com regs, inc, size, align, rm); 3229112Smarc.orr@gmail.com } 3239112Smarc.orr@gmail.com } else { 3249112Smarc.orr@gmail.com // Store instructions. 3259112Smarc.orr@gmail.com if (single) { 3269112Smarc.orr@gmail.com if (singleAll) { 3279112Smarc.orr@gmail.com return new Unknown(machInst); 3289112Smarc.orr@gmail.com } else { 3299112Smarc.orr@gmail.com return new VstSingle(machInst, false, width, rn, vd, 3309112Smarc.orr@gmail.com regs, inc, size, align, rm, lane); 3319112Smarc.orr@gmail.com } 3329112Smarc.orr@gmail.com } else { 3339112Smarc.orr@gmail.com return new VstMult(machInst, width, rn, vd, 3349112Smarc.orr@gmail.com regs, inc, size, align, rm); 3359112Smarc.orr@gmail.com } 3369112Smarc.orr@gmail.com } 3379112Smarc.orr@gmail.com return new Unknown(machInst); 3389238Slluc.alvarez@bsc.es } 3399112Smarc.orr@gmail.com ''' 3409112Smarc.orr@gmail.com 3419112Smarc.orr@gmail.com decoder_output += ''' 3429112Smarc.orr@gmail.com static StaticInstPtr 3439112Smarc.orr@gmail.com decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 3449112Smarc.orr@gmail.com { 3459112Smarc.orr@gmail.com const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 3469112Smarc.orr@gmail.com const uint32_t a = bits(machInst, 11, 8); 3479112Smarc.orr@gmail.com const bool b = bits(machInst, 4); 3489112Smarc.orr@gmail.com const uint32_t c = bits(machInst, 21, 20); 34911367Sandreas.hansson@arm.com const IntRegIndex vd = 3509112Smarc.orr@gmail.com (IntRegIndex)(2 * (bits(machInst, 15, 12) | 35111321Ssteve.reinhardt@amd.com (bits(machInst, 22) << 4))); 3529112Smarc.orr@gmail.com const IntRegIndex vn = 3539112Smarc.orr@gmail.com (IntRegIndex)(2 * (bits(machInst, 19, 16) | 3549112Smarc.orr@gmail.com (bits(machInst, 7) << 4))); 3559112Smarc.orr@gmail.com const IntRegIndex vm = 3569112Smarc.orr@gmail.com (IntRegIndex)(2 * (bits(machInst, 3, 0) | 3579112Smarc.orr@gmail.com (bits(machInst, 5) << 4))); 3589112Smarc.orr@gmail.com const unsigned size = bits(machInst, 21, 20); 3599112Smarc.orr@gmail.com const bool q = bits(machInst, 6); 3609112Smarc.orr@gmail.com if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1))) 3619112Smarc.orr@gmail.com return new Unknown(machInst); 3629112Smarc.orr@gmail.com switch (a) { 3639112Smarc.orr@gmail.com case 0x0: 3649112Smarc.orr@gmail.com if (b) { 3659112Smarc.orr@gmail.com if (u) { 3669112Smarc.orr@gmail.com return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 3679112Smarc.orr@gmail.com q, size, machInst, vd, vn, vm); 3689112Smarc.orr@gmail.com } else { 3699112Smarc.orr@gmail.com return decodeNeonSThreeReg<VqaddSD, VqaddSQ>( 3709112Smarc.orr@gmail.com q, size, machInst, vd, vn, vm); 3719112Smarc.orr@gmail.com } 3729112Smarc.orr@gmail.com } else { 3739112Smarc.orr@gmail.com if (size == 3) 3749112Smarc.orr@gmail.com return new Unknown(machInst); 3759112Smarc.orr@gmail.com return decodeNeonUSThreeReg<VhaddD, VhaddQ>( 3769112Smarc.orr@gmail.com q, u, size, machInst, vd, vn, vm); 3779112Smarc.orr@gmail.com } 3789112Smarc.orr@gmail.com case 0x1: 3799112Smarc.orr@gmail.com if (!b) { 3809112Smarc.orr@gmail.com return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>( 38111321Ssteve.reinhardt@amd.com q, u, size, machInst, vd, vn, vm); 3829112Smarc.orr@gmail.com } else { 3839112Smarc.orr@gmail.com if (u) { 3849112Smarc.orr@gmail.com switch (c) { 3859112Smarc.orr@gmail.com case 0: 3869112Smarc.orr@gmail.com if (q) { 3879112Smarc.orr@gmail.com return new VeorQ<uint64_t>(machInst, vd, vn, vm); 3889112Smarc.orr@gmail.com } else { 3899112Smarc.orr@gmail.com return new VeorD<uint64_t>(machInst, vd, vn, vm); 3909238Slluc.alvarez@bsc.es } 3919112Smarc.orr@gmail.com case 1: 3929112Smarc.orr@gmail.com if (q) { 3939112Smarc.orr@gmail.com return new VbslQ<uint64_t>(machInst, vd, vn, vm); 3949112Smarc.orr@gmail.com } else { 3959112Smarc.orr@gmail.com return new VbslD<uint64_t>(machInst, vd, vn, vm); 3962238SN/A } 3972238SN/A case 2: 3982238SN/A if (q) { 3992238SN/A return new VbitQ<uint64_t>(machInst, vd, vn, vm); 4003114Sgblack@eecs.umich.edu } else { 4012238SN/A return new VbitD<uint64_t>(machInst, vd, vn, vm); 4022238SN/A } 4032238SN/A case 3: 4043114Sgblack@eecs.umich.edu if (q) { 4052238SN/A return new VbifQ<uint64_t>(machInst, vd, vn, vm); 4062238SN/A } else { 4072238SN/A return new VbifD<uint64_t>(machInst, vd, vn, vm); 4083114Sgblack@eecs.umich.edu } 4092238SN/A } 4102238SN/A } else { 4112238SN/A switch (c) { 4123114Sgblack@eecs.umich.edu case 0: 4132238SN/A if (q) { 4142238SN/A return new VandQ<uint64_t>(machInst, vd, vn, vm); 4151354SN/A } else { 4161354SN/A return new VandD<uint64_t>(machInst, vd, vn, vm); 41710796Sbrandon.potter@amd.com } 41810796Sbrandon.potter@amd.com case 1: 4191354SN/A if (q) { 4201354SN/A return new VbicQ<uint64_t>(machInst, vd, vn, vm); 4211354SN/A } else { 4221354SN/A return new VbicD<uint64_t>(machInst, vd, vn, vm); 4231354SN/A } 4241354SN/A case 2: 4251354SN/A if (vn == vm) { 4261354SN/A if (q) { 4271354SN/A return new VmovQ<uint64_t>( 4281354SN/A machInst, vd, vn, vm); 42910796Sbrandon.potter@amd.com } else { 4301354SN/A return new VmovD<uint64_t>( 43110796Sbrandon.potter@amd.com machInst, vd, vn, vm); 4321354SN/A } 4331354SN/A } else { 4341354SN/A if (q) { 4351354SN/A return new VorrQ<uint64_t>( 43610796Sbrandon.potter@amd.com machInst, vd, vn, vm); 43710796Sbrandon.potter@amd.com } else { 43810796Sbrandon.potter@amd.com return new VorrD<uint64_t>( 43910796Sbrandon.potter@amd.com machInst, vd, vn, vm); 44010796Sbrandon.potter@amd.com } 44110796Sbrandon.potter@amd.com } 44210796Sbrandon.potter@amd.com case 3: 44310796Sbrandon.potter@amd.com if (q) { 44410796Sbrandon.potter@amd.com return new VornQ<uint64_t>( 44510796Sbrandon.potter@amd.com machInst, vd, vn, vm); 44610796Sbrandon.potter@amd.com } else { 447360SN/A return new VornD<uint64_t>( 448360SN/A machInst, vd, vn, vm); 449360SN/A } 450360SN/A } 451360SN/A } 452360SN/A } 453360SN/A case 0x2: 4543113Sgblack@eecs.umich.edu if (b) { 4553113Sgblack@eecs.umich.edu if (u) { 4563113Sgblack@eecs.umich.edu return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 4573113Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 4583113Sgblack@eecs.umich.edu } else { 4593113Sgblack@eecs.umich.edu return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 4603113Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 4613113Sgblack@eecs.umich.edu } 4623113Sgblack@eecs.umich.edu } else { 4633113Sgblack@eecs.umich.edu if (size == 3) 4643113Sgblack@eecs.umich.edu return new Unknown(machInst); 4653113Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VhsubD, VhsubQ>( 4663113Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 4673113Sgblack@eecs.umich.edu } 4683113Sgblack@eecs.umich.edu case 0x3: 4693113Sgblack@eecs.umich.edu if (b) { 4704189Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VcgeD, VcgeQ>( 4714189Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 4723113Sgblack@eecs.umich.edu } else { 4733113Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VcgtD, VcgtQ>( 4743113Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 4753113Sgblack@eecs.umich.edu } 4768737Skoansin.tan@gmail.com case 0x4: 4773113Sgblack@eecs.umich.edu if (b) { 4788737Skoansin.tan@gmail.com if (u) { 4793277Sgblack@eecs.umich.edu return decodeNeonUThreeReg<VqshlUD, VqshlUQ>( 4805515SMichael.Adler@intel.com q, size, machInst, vd, vm, vn); 4815515SMichael.Adler@intel.com } else { 4825515SMichael.Adler@intel.com return decodeNeonSThreeReg<VqshlSD, VqshlSQ>( 4835515SMichael.Adler@intel.com q, size, machInst, vd, vm, vn); 4845515SMichael.Adler@intel.com } 4858737Skoansin.tan@gmail.com } else { 4863277Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VshlD, VshlQ>( 4878737Skoansin.tan@gmail.com q, u, size, machInst, vd, vm, vn); 4883277Sgblack@eecs.umich.edu } 4898737Skoansin.tan@gmail.com case 0x5: 4903277Sgblack@eecs.umich.edu if (b) { 4918737Skoansin.tan@gmail.com if (u) { 4923113Sgblack@eecs.umich.edu return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>( 4933113Sgblack@eecs.umich.edu q, size, machInst, vd, vm, vn); 4943113Sgblack@eecs.umich.edu } else { 4953113Sgblack@eecs.umich.edu return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>( 4968737Skoansin.tan@gmail.com q, size, machInst, vd, vm, vn); 4973113Sgblack@eecs.umich.edu } 4988737Skoansin.tan@gmail.com } else { 4993114Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 5008737Skoansin.tan@gmail.com q, u, size, machInst, vd, vm, vn); 5013114Sgblack@eecs.umich.edu } 5028737Skoansin.tan@gmail.com case 0x6: 5033114Sgblack@eecs.umich.edu if (b) { 5048737Skoansin.tan@gmail.com return decodeNeonUSThreeReg<VminD, VminQ>( 5054061Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5064061Sgblack@eecs.umich.edu } else { 5074061Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VmaxD, VmaxQ>( 5088737Skoansin.tan@gmail.com q, u, size, machInst, vd, vn, vm); 5093113Sgblack@eecs.umich.edu } 5108737Skoansin.tan@gmail.com case 0x7: 5113113Sgblack@eecs.umich.edu if (b) { 5123113Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VabaD, VabaQ>( 5133113Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5143113Sgblack@eecs.umich.edu } else { 5153113Sgblack@eecs.umich.edu if (bits(machInst, 23) == 1) { 5163113Sgblack@eecs.umich.edu if (q) { 5173113Sgblack@eecs.umich.edu return new Unknown(machInst); 5183113Sgblack@eecs.umich.edu } else { 5194189Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vabdl>( 5204189Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 5213113Sgblack@eecs.umich.edu } 5223113Sgblack@eecs.umich.edu } else { 5233113Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VabdD, VabdQ>( 5248737Skoansin.tan@gmail.com q, u, size, machInst, vd, vn, vm); 5253113Sgblack@eecs.umich.edu } 5268737Skoansin.tan@gmail.com } 5273113Sgblack@eecs.umich.edu case 0x8: 5288737Skoansin.tan@gmail.com if (b) { 5293113Sgblack@eecs.umich.edu if (u) { 5303113Sgblack@eecs.umich.edu return decodeNeonUThreeReg<VceqD, VceqQ>( 5313113Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5323113Sgblack@eecs.umich.edu } else { 5333113Sgblack@eecs.umich.edu return decodeNeonUThreeReg<VtstD, VtstQ>( 5343113Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5353113Sgblack@eecs.umich.edu } 5363113Sgblack@eecs.umich.edu } else { 5373113Sgblack@eecs.umich.edu if (u) { 5383113Sgblack@eecs.umich.edu return decodeNeonUThreeReg<NVsubD, NVsubQ>( 5398852Sandreas.hansson@arm.com q, size, machInst, vd, vn, vm); 5403113Sgblack@eecs.umich.edu } else { 5413113Sgblack@eecs.umich.edu return decodeNeonUThreeReg<NVaddD, NVaddQ>( 5423113Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5433113Sgblack@eecs.umich.edu } 5443113Sgblack@eecs.umich.edu } 5453113Sgblack@eecs.umich.edu case 0x9: 5463113Sgblack@eecs.umich.edu if (b) { 5473113Sgblack@eecs.umich.edu if (u) { 5483113Sgblack@eecs.umich.edu return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 5493113Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5508852Sandreas.hansson@arm.com } else { 5513113Sgblack@eecs.umich.edu return decodeNeonSThreeReg<NVmulD, NVmulQ>( 5523113Sgblack@eecs.umich.edu q, size, machInst, vd, vn, vm); 5533113Sgblack@eecs.umich.edu } 5543113Sgblack@eecs.umich.edu } else { 5556686Stjones1@inf.ed.ac.uk if (u) { 5563113Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 5573113Sgblack@eecs.umich.edu q, u, size, machInst, vd, vn, vm); 5583113Sgblack@eecs.umich.edu } else { 559378SN/A return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 560378SN/A q, u, size, machInst, vd, vn, vm); 5619141Smarc.orr@gmail.com } 5629141Smarc.orr@gmail.com } 563360SN/A case 0xa: 5641450SN/A if (b) { 5653114Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VpminD, VpminQ>( 5662680Sktlim@umich.edu q, u, size, machInst, vd, vn, vm); 567360SN/A } else { 5686701Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>( 56910930Sbrandon.potter@amd.com q, u, size, machInst, vd, vn, vm); 5706701Sgblack@eecs.umich.edu } 571360SN/A case 0xb: 57210930Sbrandon.potter@amd.com if (b) { 573360SN/A if (u) { 57410932Sbrandon.potter@amd.com return new Unknown(machInst); 57510496Ssteve.reinhardt@amd.com } else { 57610930Sbrandon.potter@amd.com return decodeNeonUThreeReg<NVpaddD, NVpaddQ>( 577360SN/A q, size, machInst, vd, vn, vm); 5781458SN/A } 579360SN/A } else { 580360SN/A if (u) { 58110930Sbrandon.potter@amd.com return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>( 58210930Sbrandon.potter@amd.com q, size, machInst, vd, vn, vm); 58310496Ssteve.reinhardt@amd.com } else { 58410496Ssteve.reinhardt@amd.com return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>( 5859141Smarc.orr@gmail.com q, size, machInst, vd, vn, vm); 5861458SN/A } 5879141Smarc.orr@gmail.com } 588360SN/A case 0xc: 5899141Smarc.orr@gmail.com return new Unknown(machInst); 59010930Sbrandon.potter@amd.com case 0xd: 5919141Smarc.orr@gmail.com if (b) { 592360SN/A if (u) { 593360SN/A if (bits(c, 1) == 0) { 594360SN/A if (q) { 59510027SChris.Adeniyi-Jones@arm.com return new NVmulQFp<float>(machInst, vd, vn, vm); 5963114Sgblack@eecs.umich.edu } else { 59710027SChris.Adeniyi-Jones@arm.com return new NVmulDFp<float>(machInst, vd, vn, vm); 598360SN/A } 599360SN/A } else { 600360SN/A return new Unknown(machInst); 6018852Sandreas.hansson@arm.com } 6026701Sgblack@eecs.umich.edu } else { 6031458SN/A if (bits(c, 1) == 0) { 604360SN/A if (q) { 6056701Sgblack@eecs.umich.edu return new NVmlaQFp<float>(machInst, vd, vn, vm); 6066701Sgblack@eecs.umich.edu } else { 607360SN/A return new NVmlaDFp<float>(machInst, vd, vn, vm); 608360SN/A } 609360SN/A } else { 610360SN/A if (q) { 611360SN/A return new NVmlsQFp<float>(machInst, vd, vn, vm); 612360SN/A } else { 613360SN/A return new NVmlsDFp<float>(machInst, vd, vn, vm); 614360SN/A } 615360SN/A } 616360SN/A } 617360SN/A } else { 618360SN/A if (u) { 6191706SN/A if (bits(c, 1) == 0) { 620360SN/A if (q) { 621360SN/A return new VpaddQFp<float>(machInst, vd, vn, vm); 622360SN/A } else { 623360SN/A return new VpaddDFp<float>(machInst, vd, vn, vm); 624360SN/A } 6253669Sbinkertn@umich.edu } else { 6263669Sbinkertn@umich.edu if (q) { 6273669Sbinkertn@umich.edu return new VabdQFp<float>(machInst, vd, vn, vm); 6281706SN/A } else { 6291706SN/A return new VabdDFp<float>(machInst, vd, vn, vm); 63010496Ssteve.reinhardt@amd.com } 63110496Ssteve.reinhardt@amd.com } 63210496Ssteve.reinhardt@amd.com } else { 63310496Ssteve.reinhardt@amd.com if (bits(c, 1) == 0) { 63410496Ssteve.reinhardt@amd.com if (q) { 63510496Ssteve.reinhardt@amd.com return new VaddQFp<float>(machInst, vd, vn, vm); 63610496Ssteve.reinhardt@amd.com } else { 63710496Ssteve.reinhardt@amd.com return new VaddDFp<float>(machInst, vd, vn, vm); 63810496Ssteve.reinhardt@amd.com } 63910496Ssteve.reinhardt@amd.com } else { 64010496Ssteve.reinhardt@amd.com if (q) { 64110496Ssteve.reinhardt@amd.com return new VsubQFp<float>(machInst, vd, vn, vm); 64210496Ssteve.reinhardt@amd.com } else { 64310496Ssteve.reinhardt@amd.com return new VsubDFp<float>(machInst, vd, vn, vm); 64410496Ssteve.reinhardt@amd.com } 64510496Ssteve.reinhardt@amd.com } 64610496Ssteve.reinhardt@amd.com } 64710496Ssteve.reinhardt@amd.com } 64810496Ssteve.reinhardt@amd.com case 0xe: 64910496Ssteve.reinhardt@amd.com if (b) { 6505795Ssaidi@eecs.umich.edu if (u) { 6519143Ssteve.reinhardt@amd.com if (bits(c, 1) == 0) { 6529142Ssteve.reinhardt@amd.com if (q) { 6539142Ssteve.reinhardt@amd.com return new VacgeQFp<float>(machInst, vd, vn, vm); 6549143Ssteve.reinhardt@amd.com } else { 6555795Ssaidi@eecs.umich.edu return new VacgeDFp<float>(machInst, vd, vn, vm); 6569143Ssteve.reinhardt@amd.com } 6575795Ssaidi@eecs.umich.edu } else { 6585795Ssaidi@eecs.umich.edu if (q) { 6595795Ssaidi@eecs.umich.edu return new VacgtQFp<float>(machInst, vd, vn, vm); 6609143Ssteve.reinhardt@amd.com } else { 6615795Ssaidi@eecs.umich.edu return new VacgtDFp<float>(machInst, vd, vn, vm); 662360SN/A } 6639143Ssteve.reinhardt@amd.com } 6649143Ssteve.reinhardt@amd.com } else { 6659143Ssteve.reinhardt@amd.com return new Unknown(machInst); 66610932Sbrandon.potter@amd.com } 667360SN/A } else { 668360SN/A if (u) { 66910027SChris.Adeniyi-Jones@arm.com if (bits(c, 1) == 0) { 67010027SChris.Adeniyi-Jones@arm.com if (q) { 67110027SChris.Adeniyi-Jones@arm.com return new VcgeQFp<float>(machInst, vd, vn, vm); 67210027SChris.Adeniyi-Jones@arm.com } else { 67310027SChris.Adeniyi-Jones@arm.com return new VcgeDFp<float>(machInst, vd, vn, vm); 67410027SChris.Adeniyi-Jones@arm.com } 67510027SChris.Adeniyi-Jones@arm.com } else { 67610027SChris.Adeniyi-Jones@arm.com if (q) { 67710027SChris.Adeniyi-Jones@arm.com return new VcgtQFp<float>(machInst, vd, vn, vm); 67810027SChris.Adeniyi-Jones@arm.com } else { 67910027SChris.Adeniyi-Jones@arm.com return new VcgtDFp<float>(machInst, vd, vn, vm); 68010027SChris.Adeniyi-Jones@arm.com } 68110027SChris.Adeniyi-Jones@arm.com } 68210027SChris.Adeniyi-Jones@arm.com } else { 68310027SChris.Adeniyi-Jones@arm.com if (bits(c, 1) == 0) { 68410027SChris.Adeniyi-Jones@arm.com if (q) { 68510027SChris.Adeniyi-Jones@arm.com return new VceqQFp<float>(machInst, vd, vn, vm); 68610027SChris.Adeniyi-Jones@arm.com } else { 68710027SChris.Adeniyi-Jones@arm.com return new VceqDFp<float>(machInst, vd, vn, vm); 68810027SChris.Adeniyi-Jones@arm.com } 68910027SChris.Adeniyi-Jones@arm.com } else { 69010027SChris.Adeniyi-Jones@arm.com return new Unknown(machInst); 69110633Smichaelupton@gmail.com } 69210633Smichaelupton@gmail.com } 69310633Smichaelupton@gmail.com } 69410633Smichaelupton@gmail.com case 0xf: 69510633Smichaelupton@gmail.com if (b) { 69610633Smichaelupton@gmail.com if (u) { 69710633Smichaelupton@gmail.com return new Unknown(machInst); 69810633Smichaelupton@gmail.com } else { 69910633Smichaelupton@gmail.com if (bits(c, 1) == 0) { 70010633Smichaelupton@gmail.com if (q) { 70110633Smichaelupton@gmail.com return new VrecpsQFp<float>(machInst, vd, vn, vm); 70210633Smichaelupton@gmail.com } else { 70310633Smichaelupton@gmail.com return new VrecpsDFp<float>(machInst, vd, vn, vm); 70410633Smichaelupton@gmail.com } 70510203SAli.Saidi@ARM.com } else { 70610203SAli.Saidi@ARM.com if (q) { 70710203SAli.Saidi@ARM.com return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 70810203SAli.Saidi@ARM.com } else { 70910203SAli.Saidi@ARM.com return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 71010203SAli.Saidi@ARM.com } 71110203SAli.Saidi@ARM.com } 71210203SAli.Saidi@ARM.com } 71310203SAli.Saidi@ARM.com } else { 71410203SAli.Saidi@ARM.com if (u) { 71510203SAli.Saidi@ARM.com if (bits(c, 1) == 0) { 71610203SAli.Saidi@ARM.com if (q) { 71710203SAli.Saidi@ARM.com return new VpmaxQFp<float>(machInst, vd, vn, vm); 71810203SAli.Saidi@ARM.com } else { 71910203SAli.Saidi@ARM.com return new VpmaxDFp<float>(machInst, vd, vn, vm); 72010203SAli.Saidi@ARM.com } 72110203SAli.Saidi@ARM.com } else { 72210203SAli.Saidi@ARM.com if (q) { 72310203SAli.Saidi@ARM.com return new VpminQFp<float>(machInst, vd, vn, vm); 72410203SAli.Saidi@ARM.com } else { 72510203SAli.Saidi@ARM.com return new VpminDFp<float>(machInst, vd, vn, vm); 72610203SAli.Saidi@ARM.com } 72710203SAli.Saidi@ARM.com } 72810203SAli.Saidi@ARM.com } else { 72910203SAli.Saidi@ARM.com if (bits(c, 1) == 0) { 73010203SAli.Saidi@ARM.com if (q) { 73110850SGiacomo.Gabrielli@arm.com return new VmaxQFp<float>(machInst, vd, vn, vm); 73210850SGiacomo.Gabrielli@arm.com } else { 73310850SGiacomo.Gabrielli@arm.com return new VmaxDFp<float>(machInst, vd, vn, vm); 73410850SGiacomo.Gabrielli@arm.com } 73510850SGiacomo.Gabrielli@arm.com } else { 73610850SGiacomo.Gabrielli@arm.com if (q) { 73710850SGiacomo.Gabrielli@arm.com return new VminQFp<float>(machInst, vd, vn, vm); 73810850SGiacomo.Gabrielli@arm.com } else { 73910850SGiacomo.Gabrielli@arm.com return new VminDFp<float>(machInst, vd, vn, vm); 74010850SGiacomo.Gabrielli@arm.com } 74110850SGiacomo.Gabrielli@arm.com } 74210850SGiacomo.Gabrielli@arm.com } 74310850SGiacomo.Gabrielli@arm.com } 74410850SGiacomo.Gabrielli@arm.com } 74510850SGiacomo.Gabrielli@arm.com return new Unknown(machInst); 74610850SGiacomo.Gabrielli@arm.com } 74710850SGiacomo.Gabrielli@arm.com 74810850SGiacomo.Gabrielli@arm.com static StaticInstPtr 74910850SGiacomo.Gabrielli@arm.com decodeNeonOneRegModImm(ExtMachInst machInst) 75010850SGiacomo.Gabrielli@arm.com { 75110850SGiacomo.Gabrielli@arm.com const IntRegIndex vd = 75210850SGiacomo.Gabrielli@arm.com (IntRegIndex)(2 * (bits(machInst, 15, 12) | 75310850SGiacomo.Gabrielli@arm.com (bits(machInst, 22) << 4))); 75410850SGiacomo.Gabrielli@arm.com const bool q = bits(machInst, 6); 75510850SGiacomo.Gabrielli@arm.com const bool op = bits(machInst, 5); 75610850SGiacomo.Gabrielli@arm.com const uint8_t cmode = bits(machInst, 11, 8); 75710850SGiacomo.Gabrielli@arm.com const uint8_t imm = ((THUMB ? bits(machInst, 28) : 75810850SGiacomo.Gabrielli@arm.com bits(machInst, 24)) << 7) | 75910850SGiacomo.Gabrielli@arm.com (bits(machInst, 18, 16) << 4) | 76010850SGiacomo.Gabrielli@arm.com (bits(machInst, 3, 0) << 0); 76110850SGiacomo.Gabrielli@arm.com const uint64_t bigImm = simd_modified_imm(op, cmode, imm); 76210850SGiacomo.Gabrielli@arm.com if (op) { 76310850SGiacomo.Gabrielli@arm.com if (bits(cmode, 3) == 0) { 76410850SGiacomo.Gabrielli@arm.com if (bits(cmode, 0) == 0) { 76510850SGiacomo.Gabrielli@arm.com if (q) 76610850SGiacomo.Gabrielli@arm.com return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 7676640Svince@csl.cornell.edu else 7686640Svince@csl.cornell.edu return new NVmvniD<uint64_t>(machInst, vd, bigImm); 7696640Svince@csl.cornell.edu } else { 7706640Svince@csl.cornell.edu if (q) 7716640Svince@csl.cornell.edu return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 7726640Svince@csl.cornell.edu else 7736640Svince@csl.cornell.edu return new NVbiciD<uint64_t>(machInst, vd, bigImm); 7746701Sgblack@eecs.umich.edu } 7756701Sgblack@eecs.umich.edu } else { 77610793Sbrandon.potter@amd.com if (bits(cmode, 2) == 1) { 7776640Svince@csl.cornell.edu switch (bits(cmode, 1, 0)) { 7786701Sgblack@eecs.umich.edu case 0: 7796701Sgblack@eecs.umich.edu case 1: 7806640Svince@csl.cornell.edu if (q) 7818706Sandreas.hansson@arm.com return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 7826640Svince@csl.cornell.edu else 7836701Sgblack@eecs.umich.edu return new NVmvniD<uint64_t>(machInst, vd, bigImm); 7846640Svince@csl.cornell.edu case 2: 785360SN/A if (q) 7861999SN/A return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 7871999SN/A else 7881999SN/A return new NVmoviD<uint64_t>(machInst, vd, bigImm); 7893114Sgblack@eecs.umich.edu case 3: 7902680Sktlim@umich.edu if (q) 7911999SN/A return new Unknown(machInst); 7921999SN/A else 7931999SN/A return new Unknown(machInst); 7946701Sgblack@eecs.umich.edu } 7958852Sandreas.hansson@arm.com } else { 7966701Sgblack@eecs.umich.edu if (bits(cmode, 0) == 0) { 7971999SN/A if (q) 7986701Sgblack@eecs.umich.edu return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 7991999SN/A else 8006701Sgblack@eecs.umich.edu return new NVmvniD<uint64_t>(machInst, vd, bigImm); 8011999SN/A } else { 8021999SN/A if (q) 8031999SN/A return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 8041999SN/A else 8051999SN/A return new NVbiciD<uint64_t>(machInst, vd, bigImm); 8063669Sbinkertn@umich.edu } 8073669Sbinkertn@umich.edu } 8083669Sbinkertn@umich.edu } 8091999SN/A } else { 8101999SN/A if (bits(cmode, 3) == 0) { 8111999SN/A if (bits(cmode, 0) == 0) { 8122218SN/A if (q) 8131999SN/A return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8141999SN/A else 8151999SN/A return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8161999SN/A } else { 8171999SN/A if (q) 8181999SN/A return new NVorriQ<uint64_t>(machInst, vd, bigImm); 8191999SN/A else 8201999SN/A return new NVorriD<uint64_t>(machInst, vd, bigImm); 8213114Sgblack@eecs.umich.edu } 8222680Sktlim@umich.edu } else { 8231999SN/A if (bits(cmode, 2) == 1) { 8246701Sgblack@eecs.umich.edu if (q) 82510931Sbrandon.potter@amd.com return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 82610931Sbrandon.potter@amd.com else 82710931Sbrandon.potter@amd.com return new NVmoviD<uint64_t>(machInst, vd, bigImm); 82810932Sbrandon.potter@amd.com } else { 82910931Sbrandon.potter@amd.com if (bits(cmode, 0) == 0) { 8301999SN/A if (q) 8311999SN/A return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 8321999SN/A else 8331999SN/A return new NVmoviD<uint64_t>(machInst, vd, bigImm); 8341999SN/A } else { 8351999SN/A if (q) 8361999SN/A return new NVorriQ<uint64_t>(machInst, vd, bigImm); 8371999SN/A else 83810931Sbrandon.potter@amd.com return new NVorriD<uint64_t>(machInst, vd, bigImm); 8391999SN/A } 8402218SN/A } 8411999SN/A } 8421999SN/A } 8431999SN/A return new Unknown(machInst); 8441999SN/A } 8455877Shsul@eecs.umich.edu 8465877Shsul@eecs.umich.edu static StaticInstPtr 8475877Shsul@eecs.umich.edu decodeNeonTwoRegAndShift(ExtMachInst machInst) 8485877Shsul@eecs.umich.edu { 8495877Shsul@eecs.umich.edu const uint32_t a = bits(machInst, 11, 8); 8506701Sgblack@eecs.umich.edu const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 8516701Sgblack@eecs.umich.edu const bool b = bits(machInst, 6); 8526701Sgblack@eecs.umich.edu const bool l = bits(machInst, 7); 8536701Sgblack@eecs.umich.edu const IntRegIndex vd = 8546701Sgblack@eecs.umich.edu (IntRegIndex)(2 * (bits(machInst, 15, 12) | 85510027SChris.Adeniyi-Jones@arm.com (bits(machInst, 22) << 4))); 85610027SChris.Adeniyi-Jones@arm.com const IntRegIndex vm = 85710027SChris.Adeniyi-Jones@arm.com (IntRegIndex)(2 * (bits(machInst, 3, 0) | 85810027SChris.Adeniyi-Jones@arm.com (bits(machInst, 5) << 4))); 85910027SChris.Adeniyi-Jones@arm.com unsigned imm6 = bits(machInst, 21, 16); 8605877Shsul@eecs.umich.edu unsigned imm = ((l ? 1 : 0) << 6) | imm6; 86110318Sandreas.hansson@arm.com unsigned size = 3; 86210318Sandreas.hansson@arm.com unsigned lShiftAmt = 0; 8635877Shsul@eecs.umich.edu unsigned bitSel; 8645877Shsul@eecs.umich.edu for (bitSel = 1 << 6; true; bitSel >>= 1) { 8655877Shsul@eecs.umich.edu if (bitSel & imm) 8665877Shsul@eecs.umich.edu break; 86710486Stjablin@gmail.com else if (!size) 86810486Stjablin@gmail.com return new Unknown(machInst); 8695877Shsul@eecs.umich.edu size--; 87010027SChris.Adeniyi-Jones@arm.com } 87110027SChris.Adeniyi-Jones@arm.com lShiftAmt = imm6 & ~bitSel; 8725877Shsul@eecs.umich.edu unsigned rShiftAmt = 0; 8738601Ssteve.reinhardt@amd.com if (a != 0xe && a != 0xf) { 8745877Shsul@eecs.umich.edu if (size > 2) 8755877Shsul@eecs.umich.edu rShiftAmt = 64 - imm6; 8765877Shsul@eecs.umich.edu else 87710027SChris.Adeniyi-Jones@arm.com rShiftAmt = 2 * (8 << size) - imm6; 8785877Shsul@eecs.umich.edu } 8795877Shsul@eecs.umich.edu 8805877Shsul@eecs.umich.edu switch (a) { 88110027SChris.Adeniyi-Jones@arm.com case 0x0: 88210027SChris.Adeniyi-Jones@arm.com return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 88310027SChris.Adeniyi-Jones@arm.com b, u, size, machInst, vd, vm, rShiftAmt); 88410027SChris.Adeniyi-Jones@arm.com case 0x1: 88510027SChris.Adeniyi-Jones@arm.com return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 88610027SChris.Adeniyi-Jones@arm.com b, u, size, machInst, vd, vm, rShiftAmt); 8875877Shsul@eecs.umich.edu case 0x2: 88810027SChris.Adeniyi-Jones@arm.com return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 88910027SChris.Adeniyi-Jones@arm.com b, u, size, machInst, vd, vm, rShiftAmt); 89010027SChris.Adeniyi-Jones@arm.com case 0x3: 89110027SChris.Adeniyi-Jones@arm.com return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 89210027SChris.Adeniyi-Jones@arm.com b, u, size, machInst, vd, vm, rShiftAmt); 89310027SChris.Adeniyi-Jones@arm.com case 0x4: 89410027SChris.Adeniyi-Jones@arm.com if (u) { 89510027SChris.Adeniyi-Jones@arm.com return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 89610027SChris.Adeniyi-Jones@arm.com b, size, machInst, vd, vm, rShiftAmt); 89710027SChris.Adeniyi-Jones@arm.com } else { 89810027SChris.Adeniyi-Jones@arm.com return new Unknown(machInst); 89910027SChris.Adeniyi-Jones@arm.com } 90010027SChris.Adeniyi-Jones@arm.com case 0x5: 9015877Shsul@eecs.umich.edu if (u) { 9025877Shsul@eecs.umich.edu return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 9035877Shsul@eecs.umich.edu b, size, machInst, vd, vm, lShiftAmt); 90410027SChris.Adeniyi-Jones@arm.com } else { 90510027SChris.Adeniyi-Jones@arm.com return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 9068601Ssteve.reinhardt@amd.com b, size, machInst, vd, vm, lShiftAmt); 90710027SChris.Adeniyi-Jones@arm.com } 9085877Shsul@eecs.umich.edu case 0x6: 9095877Shsul@eecs.umich.edu case 0x7: 9101999SN/A if (u) { 911378SN/A if (a == 0x6) { 912360SN/A return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 9131450SN/A b, size, machInst, vd, vm, lShiftAmt); 9143114Sgblack@eecs.umich.edu } else { 9152680Sktlim@umich.edu return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 916360SN/A b, size, machInst, vd, vm, lShiftAmt); 917360SN/A } 918360SN/A } else { 9196701Sgblack@eecs.umich.edu return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 9208852Sandreas.hansson@arm.com b, size, machInst, vd, vm, lShiftAmt); 9216701Sgblack@eecs.umich.edu } 9226701Sgblack@eecs.umich.edu case 0x8: 9236701Sgblack@eecs.umich.edu if (l) { 9246701Sgblack@eecs.umich.edu return new Unknown(machInst); 925360SN/A } else if (u) { 9263669Sbinkertn@umich.edu return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 9273669Sbinkertn@umich.edu b, size, machInst, vd, vm, rShiftAmt); 9283669Sbinkertn@umich.edu } else { 929360SN/A return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 930360SN/A b, size, machInst, vd, vm, rShiftAmt); 931360SN/A } 932360SN/A case 0x9: 9332218SN/A if (l) { 934360SN/A return new Unknown(machInst); 9358706Sandreas.hansson@arm.com } else if (u) { 936360SN/A return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 9371458SN/A b, size, machInst, vd, vm, rShiftAmt); 938360SN/A } else { 939360SN/A return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 940360SN/A b, size, machInst, vd, vm, rShiftAmt); 9415074Ssaidi@eecs.umich.edu } 9425074Ssaidi@eecs.umich.edu case 0xa: 9435074Ssaidi@eecs.umich.edu if (l || b) { 9445074Ssaidi@eecs.umich.edu return new Unknown(machInst); 9455074Ssaidi@eecs.umich.edu } else { 9465074Ssaidi@eecs.umich.edu return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 9475074Ssaidi@eecs.umich.edu lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); 9485074Ssaidi@eecs.umich.edu } 9496701Sgblack@eecs.umich.edu case 0xe: 9508852Sandreas.hansson@arm.com if (l) { 9516701Sgblack@eecs.umich.edu return new Unknown(machInst); 9525074Ssaidi@eecs.umich.edu } else { 9536701Sgblack@eecs.umich.edu if (bits(imm6, 5) == 0) 9545074Ssaidi@eecs.umich.edu return new Unknown(machInst); 9555074Ssaidi@eecs.umich.edu if (u) { 9565074Ssaidi@eecs.umich.edu if (b) { 9575074Ssaidi@eecs.umich.edu return new NVcvtu2fpQ<float>( 9585208Ssaidi@eecs.umich.edu machInst, vd, vm, 64 - imm6); 9595208Ssaidi@eecs.umich.edu } else { 9605208Ssaidi@eecs.umich.edu return new NVcvtu2fpD<float>( 9615208Ssaidi@eecs.umich.edu machInst, vd, vm, 64 - imm6); 9625074Ssaidi@eecs.umich.edu } 9635074Ssaidi@eecs.umich.edu } else { 9645208Ssaidi@eecs.umich.edu if (b) { 9655074Ssaidi@eecs.umich.edu return new NVcvts2fpQ<float>( 9665074Ssaidi@eecs.umich.edu machInst, vd, vm, 64 - imm6); 9675074Ssaidi@eecs.umich.edu } else { 9685074Ssaidi@eecs.umich.edu return new NVcvts2fpD<float>( 9698706Sandreas.hansson@arm.com machInst, vd, vm, 64 - imm6); 9705074Ssaidi@eecs.umich.edu } 9715074Ssaidi@eecs.umich.edu } 9725074Ssaidi@eecs.umich.edu } 9735074Ssaidi@eecs.umich.edu case 0xf: 9745074Ssaidi@eecs.umich.edu if (l) { 97510027SChris.Adeniyi-Jones@arm.com return new Unknown(machInst); 97610027SChris.Adeniyi-Jones@arm.com } else { 97710027SChris.Adeniyi-Jones@arm.com if (bits(imm6, 5) == 0) 97810027SChris.Adeniyi-Jones@arm.com return new Unknown(machInst); 97910027SChris.Adeniyi-Jones@arm.com if (u) { 98010027SChris.Adeniyi-Jones@arm.com if (b) { 98110027SChris.Adeniyi-Jones@arm.com return new NVcvt2ufxQ<float>( 98210027SChris.Adeniyi-Jones@arm.com machInst, vd, vm, 64 - imm6); 98310027SChris.Adeniyi-Jones@arm.com } else { 98410793Sbrandon.potter@amd.com return new NVcvt2ufxD<float>( 98510027SChris.Adeniyi-Jones@arm.com machInst, vd, vm, 64 - imm6); 98610027SChris.Adeniyi-Jones@arm.com } 98710027SChris.Adeniyi-Jones@arm.com } else { 98810027SChris.Adeniyi-Jones@arm.com if (b) { 98910027SChris.Adeniyi-Jones@arm.com return new NVcvt2sfxQ<float>( 99010027SChris.Adeniyi-Jones@arm.com machInst, vd, vm, 64 - imm6); 99110027SChris.Adeniyi-Jones@arm.com } else { 99210027SChris.Adeniyi-Jones@arm.com return new NVcvt2sfxD<float>( 99310027SChris.Adeniyi-Jones@arm.com machInst, vd, vm, 64 - imm6); 99410027SChris.Adeniyi-Jones@arm.com } 99510027SChris.Adeniyi-Jones@arm.com } 99610027SChris.Adeniyi-Jones@arm.com } 99710027SChris.Adeniyi-Jones@arm.com } 99810027SChris.Adeniyi-Jones@arm.com return new Unknown(machInst); 99910027SChris.Adeniyi-Jones@arm.com } 100010027SChris.Adeniyi-Jones@arm.com 100110027SChris.Adeniyi-Jones@arm.com static StaticInstPtr 100210027SChris.Adeniyi-Jones@arm.com decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 100310027SChris.Adeniyi-Jones@arm.com { 100410027SChris.Adeniyi-Jones@arm.com const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 100510027SChris.Adeniyi-Jones@arm.com const uint32_t a = bits(machInst, 11, 8); 100610027SChris.Adeniyi-Jones@arm.com const IntRegIndex vd = 100710027SChris.Adeniyi-Jones@arm.com (IntRegIndex)(2 * (bits(machInst, 15, 12) | 100810027SChris.Adeniyi-Jones@arm.com (bits(machInst, 22) << 4))); 100910027SChris.Adeniyi-Jones@arm.com const IntRegIndex vn = 101010027SChris.Adeniyi-Jones@arm.com (IntRegIndex)(2 * (bits(machInst, 19, 16) | 101110027SChris.Adeniyi-Jones@arm.com (bits(machInst, 7) << 4))); 10121999SN/A const IntRegIndex vm = 10131999SN/A (IntRegIndex)(2 * (bits(machInst, 3, 0) | 10141999SN/A (bits(machInst, 5) << 4))); 10153114Sgblack@eecs.umich.edu const unsigned size = bits(machInst, 21, 20); 10162680Sktlim@umich.edu switch (a) { 10171999SN/A case 0x0: 10186701Sgblack@eecs.umich.edu return decodeNeonUSThreeUSReg<Vaddl>( 101910931Sbrandon.potter@amd.com u, size, machInst, vd, vn, vm); 10206701Sgblack@eecs.umich.edu case 0x1: 102110931Sbrandon.potter@amd.com return decodeNeonUSThreeUSReg<Vaddw>( 102210932Sbrandon.potter@amd.com u, size, machInst, vd, vn, vm); 102310931Sbrandon.potter@amd.com case 0x2: 10241999SN/A return decodeNeonUSThreeUSReg<Vsubl>( 10251999SN/A u, size, machInst, vd, vn, vm); 10262764Sstever@eecs.umich.edu case 0x3: 10272064SN/A return decodeNeonUSThreeUSReg<Vsubw>( 102810931Sbrandon.potter@amd.com u, size, machInst, vd, vn, vm); 10292064SN/A case 0x4: 10302064SN/A if (u) { 103110931Sbrandon.potter@amd.com return decodeNeonUThreeUSReg<Vraddhn>( 10322064SN/A size, machInst, vd, vn, vm); 10331999SN/A } else { 10341999SN/A return decodeNeonUThreeUSReg<Vaddhn>( 10352218SN/A size, machInst, vd, vn, vm); 10361999SN/A } 103710931Sbrandon.potter@amd.com case 0x5: 10381999SN/A return decodeNeonUSThreeUSReg<Vabal>( 10391999SN/A u, size, machInst, vd, vn, vm); 10401999SN/A case 0x6: 10411999SN/A if (u) { 10421999SN/A return decodeNeonUThreeUSReg<Vrsubhn>( 1043378SN/A size, machInst, vd, vn, vm); 1044360SN/A } else { 10451450SN/A return decodeNeonUThreeUSReg<Vsubhn>( 10463114Sgblack@eecs.umich.edu size, machInst, vd, vn, vm); 10472680Sktlim@umich.edu } 1048360SN/A case 0x7: 1049360SN/A if (bits(machInst, 23)) { 1050360SN/A return decodeNeonUSThreeUSReg<Vabdl>( 10516701Sgblack@eecs.umich.edu u, size, machInst, vd, vn, vm); 10528852Sandreas.hansson@arm.com } else { 10536701Sgblack@eecs.umich.edu return decodeNeonUSThreeReg<VabdD, VabdQ>( 10546701Sgblack@eecs.umich.edu bits(machInst, 6), u, size, machInst, vd, vn, vm); 10556701Sgblack@eecs.umich.edu } 10566701Sgblack@eecs.umich.edu case 0x8: 1057360SN/A return decodeNeonUSThreeUSReg<Vmlal>( 10583669Sbinkertn@umich.edu u, size, machInst, vd, vn, vm); 10593669Sbinkertn@umich.edu case 0xa: 10603669Sbinkertn@umich.edu return decodeNeonUSThreeUSReg<Vmlsl>( 1061360SN/A u, size, machInst, vd, vn, vm); 1062360SN/A case 0x9: 1063360SN/A if (u) { 1064360SN/A return new Unknown(machInst); 10651458SN/A } else { 1066360SN/A return decodeNeonSThreeUSReg<Vqdmlal>( 10678706Sandreas.hansson@arm.com size, machInst, vd, vn, vm); 1068360SN/A } 10691458SN/A case 0xb: 1070360SN/A if (u) { 1071360SN/A return new Unknown(machInst); 10721999SN/A } else { 10731999SN/A return decodeNeonSThreeUSReg<Vqdmlsl>( 10741999SN/A size, machInst, vd, vn, vm); 10753114Sgblack@eecs.umich.edu } 10762680Sktlim@umich.edu case 0xc: 10771999SN/A return decodeNeonUSThreeUSReg<Vmull>( 10781999SN/A u, size, machInst, vd, vn, vm); 10791999SN/A case 0xd: 10806701Sgblack@eecs.umich.edu if (u) { 10818852Sandreas.hansson@arm.com return new Unknown(machInst); 10826701Sgblack@eecs.umich.edu } else { 10836701Sgblack@eecs.umich.edu return decodeNeonSThreeUSReg<Vqdmull>( 10846701Sgblack@eecs.umich.edu size, machInst, vd, vn, vm); 10856701Sgblack@eecs.umich.edu } 10861999SN/A case 0xe: 10873669Sbinkertn@umich.edu return decodeNeonUThreeUSReg<Vmullp>( 10883669Sbinkertn@umich.edu size, machInst, vd, vn, vm); 10893669Sbinkertn@umich.edu } 10902764Sstever@eecs.umich.edu return new Unknown(machInst); 10912064SN/A } 10922064SN/A 10932064SN/A static StaticInstPtr 10941999SN/A decodeNeonTwoRegScalar(ExtMachInst machInst) 10951999SN/A { 10962064SN/A const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 10971999SN/A const uint32_t a = bits(machInst, 11, 8); 10981999SN/A const unsigned size = bits(machInst, 21, 20); 10991999SN/A const IntRegIndex vd = 11001999SN/A (IntRegIndex)(2 * (bits(machInst, 15, 12) | 11018706Sandreas.hansson@arm.com (bits(machInst, 22) << 4))); 11021999SN/A const IntRegIndex vn = 11031999SN/A (IntRegIndex)(2 * (bits(machInst, 19, 16) | 11041999SN/A (bits(machInst, 7) << 4))); 11051999SN/A const IntRegIndex vm = (size == 2) ? 1106378SN/A (IntRegIndex)(2 * bits(machInst, 3, 0)) : 1107360SN/A (IntRegIndex)(2 * bits(machInst, 2, 0)); 11081450SN/A const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 11093114Sgblack@eecs.umich.edu (bits(machInst, 3) | (bits(machInst, 5) << 1)); 11102680Sktlim@umich.edu switch (a) { 1111360SN/A case 0x0: 11126701Sgblack@eecs.umich.edu if (u) { 111310931Sbrandon.potter@amd.com switch (size) { 11146701Sgblack@eecs.umich.edu case 1: 1115360SN/A return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 111611380Salexandru.dutu@amd.com case 2: 1117360SN/A return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index); 111810932Sbrandon.potter@amd.com default: 111910931Sbrandon.potter@amd.com return new Unknown(machInst); 11201458SN/A } 1121360SN/A } else { 1122360SN/A switch (size) { 112310931Sbrandon.potter@amd.com case 1: 1124360SN/A return new VmlasD<uint16_t>(machInst, vd, vn, vm, index); 1125360SN/A case 2: 11261458SN/A return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 1127360SN/A default: 112810931Sbrandon.potter@amd.com return new Unknown(machInst); 11292021SN/A } 11301458SN/A } 1131360SN/A case 0x1: 1132360SN/A if (u) 1133360SN/A return new VmlasQFp<float>(machInst, vd, vn, vm, index); 11341706SN/A else 11351706SN/A return new VmlasDFp<float>(machInst, vd, vn, vm, index); 11361706SN/A case 0x4: 11373114Sgblack@eecs.umich.edu if (u) { 11382680Sktlim@umich.edu switch (size) { 11391706SN/A case 1: 11401706SN/A return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 11411706SN/A case 2: 11426701Sgblack@eecs.umich.edu return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index); 11438852Sandreas.hansson@arm.com default: 11446701Sgblack@eecs.umich.edu return new Unknown(machInst); 11456701Sgblack@eecs.umich.edu } 11466701Sgblack@eecs.umich.edu } else { 11476701Sgblack@eecs.umich.edu switch (size) { 11481706SN/A case 1: 11493669Sbinkertn@umich.edu return new VmlssD<uint16_t>(machInst, vd, vn, vm, index); 11503669Sbinkertn@umich.edu case 2: 11513669Sbinkertn@umich.edu return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 11521706SN/A default: 11531706SN/A return new Unknown(machInst); 11541706SN/A } 11551706SN/A } 11562218SN/A case 0x5: 11571706SN/A if (u) 11588706Sandreas.hansson@arm.com return new VmlssQFp<float>(machInst, vd, vn, vm, index); 11591706SN/A else 11601706SN/A return new VmlssDFp<float>(machInst, vd, vn, vm, index); 11611706SN/A case 0x2: 11621706SN/A if (u) { 11631706SN/A switch (size) { 11641706SN/A case 1: 11651706SN/A return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 11661706SN/A case 2: 11673114Sgblack@eecs.umich.edu return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 11682680Sktlim@umich.edu default: 11691706SN/A return new Unknown(machInst); 11706701Sgblack@eecs.umich.edu } 117110931Sbrandon.potter@amd.com } else { 11726701Sgblack@eecs.umich.edu switch (size) { 11731706SN/A case 1: 117410932Sbrandon.potter@amd.com return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 117510931Sbrandon.potter@amd.com case 2: 11761706SN/A return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 11771706SN/A default: 11781706SN/A return new Unknown(machInst); 117910931Sbrandon.potter@amd.com } 11801706SN/A } 11811706SN/A case 0x6: 11822218SN/A if (u) { 11831706SN/A switch (size) { 11848706Sandreas.hansson@arm.com case 1: 11851706SN/A return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 11861706SN/A case 2: 11871706SN/A return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 11881706SN/A default: 11891706SN/A return new Unknown(machInst); 11901999SN/A } 11911999SN/A } else { 11921999SN/A switch (size) { 11933114Sgblack@eecs.umich.edu case 1: 11942680Sktlim@umich.edu return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 11951999SN/A case 2: 11966701Sgblack@eecs.umich.edu return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 119710931Sbrandon.potter@amd.com default: 119810931Sbrandon.potter@amd.com return new Unknown(machInst); 119910932Sbrandon.potter@amd.com } 120010931Sbrandon.potter@amd.com } 12011999SN/A case 0x3: 12021999SN/A if (u) { 12038852Sandreas.hansson@arm.com return new Unknown(machInst); 12046701Sgblack@eecs.umich.edu } else { 12056701Sgblack@eecs.umich.edu switch (size) { 12061999SN/A case 1: 12076227Snate@binkert.org return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 12081999SN/A case 2: 12092461SN/A return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 12108852Sandreas.hansson@arm.com default: 12118852Sandreas.hansson@arm.com return new Unknown(machInst); 12128737Skoansin.tan@gmail.com } 12131999SN/A } 12148852Sandreas.hansson@arm.com case 0x7: 12158852Sandreas.hansson@arm.com if (u) { 12161999SN/A return new Unknown(machInst); 12171999SN/A } else { 121810931Sbrandon.potter@amd.com switch (size) { 12191999SN/A case 1: 12206227Snate@binkert.org return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 12211999SN/A case 2: 12221999SN/A return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 12231999SN/A default: 12242218SN/A return new Unknown(machInst); 12251999SN/A } 122610629Sjthestness@gmail.com } 12271999SN/A case 0x8: 12281999SN/A if (u) { 122911385Sbrandon.potter@amd.com switch (size) { 1230360SN/A case 1: 12311450SN/A return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 123211385Sbrandon.potter@amd.com case 2: 123311385Sbrandon.potter@amd.com return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index); 1234360SN/A default: 12356701Sgblack@eecs.umich.edu return new Unknown(machInst); 12366701Sgblack@eecs.umich.edu } 12376701Sgblack@eecs.umich.edu } else { 123811383Sbrandon.potter@amd.com switch (size) { 123911383Sbrandon.potter@amd.com case 1: 12408324Ssteve.reinhardt@amd.com return new VmulsD<uint16_t>(machInst, vd, vn, vm, index); 124110486Stjablin@gmail.com case 2: 1242360SN/A return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 124311385Sbrandon.potter@amd.com default: 124411385Sbrandon.potter@amd.com return new Unknown(machInst); 12459008Sgblack@eecs.umich.edu } 124611383Sbrandon.potter@amd.com } 124711383Sbrandon.potter@amd.com case 0x9: 124811383Sbrandon.potter@amd.com if (u) 124911383Sbrandon.potter@amd.com return new VmulsQFp<float>(machInst, vd, vn, vm, index); 125011383Sbrandon.potter@amd.com else 125111383Sbrandon.potter@amd.com return new VmulsDFp<float>(machInst, vd, vn, vm, index); 125211383Sbrandon.potter@amd.com case 0xa: 125311383Sbrandon.potter@amd.com if (u) { 125411383Sbrandon.potter@amd.com switch (size) { 12558324Ssteve.reinhardt@amd.com case 1: 125611383Sbrandon.potter@amd.com return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 125711383Sbrandon.potter@amd.com case 2: 125811383Sbrandon.potter@amd.com return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 125911383Sbrandon.potter@amd.com default: 126011383Sbrandon.potter@amd.com return new Unknown(machInst); 126111383Sbrandon.potter@amd.com } 126211383Sbrandon.potter@amd.com } else { 126311383Sbrandon.potter@amd.com switch (size) { 126411383Sbrandon.potter@amd.com case 1: 126511383Sbrandon.potter@amd.com return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 126611383Sbrandon.potter@amd.com case 2: 126711383Sbrandon.potter@amd.com return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 126811383Sbrandon.potter@amd.com default: 126911383Sbrandon.potter@amd.com return new Unknown(machInst); 127011383Sbrandon.potter@amd.com } 127111383Sbrandon.potter@amd.com } 127211383Sbrandon.potter@amd.com case 0xb: 127311383Sbrandon.potter@amd.com if (u) { 127411383Sbrandon.potter@amd.com return new Unknown(machInst); 127511383Sbrandon.potter@amd.com } else { 127611383Sbrandon.potter@amd.com if (u) { 127711383Sbrandon.potter@amd.com switch (size) { 127811383Sbrandon.potter@amd.com case 1: 127911383Sbrandon.potter@amd.com return new Vqdmulls<uint16_t>( 12808324Ssteve.reinhardt@amd.com machInst, vd, vn, vm, index); 12815877Shsul@eecs.umich.edu case 2: 128210486Stjablin@gmail.com return new Vqdmulls<uint32_t>( 128310486Stjablin@gmail.com machInst, vd, vn, vm, index); 128411383Sbrandon.potter@amd.com default: 128511383Sbrandon.potter@amd.com return new Unknown(machInst); 128611383Sbrandon.potter@amd.com } 128711624Smichael.lebeane@amd.com } else { 128811624Smichael.lebeane@amd.com switch (size) { 128911624Smichael.lebeane@amd.com case 1: 129011624Smichael.lebeane@amd.com return new Vqdmulls<int16_t>( 129111624Smichael.lebeane@amd.com machInst, vd, vn, vm, index); 129211624Smichael.lebeane@amd.com case 2: 129311624Smichael.lebeane@amd.com return new Vqdmulls<int32_t>( 129411624Smichael.lebeane@amd.com machInst, vd, vn, vm, index); 129511624Smichael.lebeane@amd.com default: 129611624Smichael.lebeane@amd.com return new Unknown(machInst); 129711624Smichael.lebeane@amd.com } 129811383Sbrandon.potter@amd.com } 129911383Sbrandon.potter@amd.com } 1300360SN/A case 0xc: 130111383Sbrandon.potter@amd.com if (u) { 130211383Sbrandon.potter@amd.com switch (size) { 13038600Ssteve.reinhardt@amd.com case 1: 130411383Sbrandon.potter@amd.com return new VqdmulhsQ<int16_t>( 130511383Sbrandon.potter@amd.com machInst, vd, vn, vm, index); 130611383Sbrandon.potter@amd.com case 2: 13078600Ssteve.reinhardt@amd.com return new VqdmulhsQ<int32_t>( 13082544SN/A machInst, vd, vn, vm, index); 13092544SN/A default: 131011383Sbrandon.potter@amd.com return new Unknown(machInst); 131111383Sbrandon.potter@amd.com } 131211383Sbrandon.potter@amd.com } else { 131311386Ssteve.reinhardt@amd.com switch (size) { 131411386Ssteve.reinhardt@amd.com case 1: 131511383Sbrandon.potter@amd.com return new VqdmulhsD<int16_t>( 131611383Sbrandon.potter@amd.com machInst, vd, vn, vm, index); 131711383Sbrandon.potter@amd.com case 2: 131811383Sbrandon.potter@amd.com return new VqdmulhsD<int32_t>( 131911383Sbrandon.potter@amd.com machInst, vd, vn, vm, index); 132011383Sbrandon.potter@amd.com default: 132111383Sbrandon.potter@amd.com return new Unknown(machInst); 132211383Sbrandon.potter@amd.com } 132311383Sbrandon.potter@amd.com } 132411383Sbrandon.potter@amd.com case 0xd: 132511383Sbrandon.potter@amd.com if (u) { 132611383Sbrandon.potter@amd.com switch (size) { 132711383Sbrandon.potter@amd.com case 1: 132811383Sbrandon.potter@amd.com return new VqrdmulhsQ<int16_t>( 132911383Sbrandon.potter@amd.com machInst, vd, vn, vm, index); 13308600Ssteve.reinhardt@amd.com case 2: 13316672Sgblack@eecs.umich.edu return new VqrdmulhsQ<int32_t>( 13328600Ssteve.reinhardt@amd.com machInst, vd, vn, vm, index); 133311383Sbrandon.potter@amd.com default: 133411383Sbrandon.potter@amd.com return new Unknown(machInst); 133511383Sbrandon.potter@amd.com } 13368601Ssteve.reinhardt@amd.com } else { 13372544SN/A switch (size) { 133811383Sbrandon.potter@amd.com case 1: 133911383Sbrandon.potter@amd.com return new VqrdmulhsD<int16_t>( 134011383Sbrandon.potter@amd.com machInst, vd, vn, vm, index); 134111383Sbrandon.potter@amd.com case 2: 134211383Sbrandon.potter@amd.com return new VqrdmulhsD<int32_t>( 134311383Sbrandon.potter@amd.com machInst, vd, vn, vm, index); 134411383Sbrandon.potter@amd.com default: 134511383Sbrandon.potter@amd.com return new Unknown(machInst); 134611383Sbrandon.potter@amd.com } 134711383Sbrandon.potter@amd.com } 134811383Sbrandon.potter@amd.com } 134911383Sbrandon.potter@amd.com return new Unknown(machInst); 135011383Sbrandon.potter@amd.com } 135111383Sbrandon.potter@amd.com 135211383Sbrandon.potter@amd.com static StaticInstPtr 135311383Sbrandon.potter@amd.com decodeNeonTwoRegMisc(ExtMachInst machInst) 135411383Sbrandon.potter@amd.com { 135511383Sbrandon.potter@amd.com const uint32_t a = bits(machInst, 17, 16); 135611383Sbrandon.potter@amd.com const uint32_t b = bits(machInst, 10, 6); 135711383Sbrandon.potter@amd.com const bool q = bits(machInst, 6); 135811383Sbrandon.potter@amd.com const IntRegIndex vd = 135911383Sbrandon.potter@amd.com (IntRegIndex)(2 * (bits(machInst, 15, 12) | 136011383Sbrandon.potter@amd.com (bits(machInst, 22) << 4))); 136111383Sbrandon.potter@amd.com const IntRegIndex vm = 136211383Sbrandon.potter@amd.com (IntRegIndex)(2 * (bits(machInst, 3, 0) | 136311383Sbrandon.potter@amd.com (bits(machInst, 5) << 4))); 136411383Sbrandon.potter@amd.com const unsigned size = bits(machInst, 19, 18); 136511383Sbrandon.potter@amd.com switch (a) { 136611383Sbrandon.potter@amd.com case 0x0: 136711383Sbrandon.potter@amd.com switch (bits(b, 4, 1)) { 136811383Sbrandon.potter@amd.com case 0x0: 136911383Sbrandon.potter@amd.com switch (size) { 137011392Sbrandon.potter@amd.com case 0: 137111392Sbrandon.potter@amd.com if (q) { 137211392Sbrandon.potter@amd.com return new NVrev64Q<uint8_t>(machInst, vd, vm); 137311392Sbrandon.potter@amd.com } else { 137411392Sbrandon.potter@amd.com return new NVrev64D<uint8_t>(machInst, vd, vm); 137511392Sbrandon.potter@amd.com } 137611392Sbrandon.potter@amd.com case 1: 137711392Sbrandon.potter@amd.com if (q) { 137811392Sbrandon.potter@amd.com return new NVrev64Q<uint16_t>(machInst, vd, vm); 137911392Sbrandon.potter@amd.com } else { 138011392Sbrandon.potter@amd.com return new NVrev64D<uint16_t>(machInst, vd, vm); 138111392Sbrandon.potter@amd.com } 138211392Sbrandon.potter@amd.com case 2: 138311392Sbrandon.potter@amd.com if (q) { 138411392Sbrandon.potter@amd.com return new NVrev64Q<uint32_t>(machInst, vd, vm); 138511392Sbrandon.potter@amd.com } else { 138611392Sbrandon.potter@amd.com return new NVrev64D<uint32_t>(machInst, vd, vm); 138711392Sbrandon.potter@amd.com } 138811392Sbrandon.potter@amd.com default: 138911392Sbrandon.potter@amd.com return new Unknown(machInst); 139011392Sbrandon.potter@amd.com } 139111392Sbrandon.potter@amd.com case 0x1: 139211392Sbrandon.potter@amd.com switch (size) { 139311392Sbrandon.potter@amd.com case 0: 139411392Sbrandon.potter@amd.com if (q) { 139511383Sbrandon.potter@amd.com return new NVrev32Q<uint8_t>(machInst, vd, vm); 139611383Sbrandon.potter@amd.com } else { 139711383Sbrandon.potter@amd.com return new NVrev32D<uint8_t>(machInst, vd, vm); 139811383Sbrandon.potter@amd.com } 139911383Sbrandon.potter@amd.com case 1: 14001458SN/A if (q) { 1401360SN/A return new NVrev32Q<uint16_t>(machInst, vd, vm); 1402360SN/A } else { 140311593Santhony.gutierrez@amd.com return new NVrev32D<uint16_t>(machInst, vd, vm); 140411593Santhony.gutierrez@amd.com } 140511593Santhony.gutierrez@amd.com default: 140611593Santhony.gutierrez@amd.com return new Unknown(machInst); 140711593Santhony.gutierrez@amd.com } 140811593Santhony.gutierrez@amd.com case 0x2: 140911593Santhony.gutierrez@amd.com if (size != 0) { 141011593Santhony.gutierrez@amd.com return new Unknown(machInst); 141111593Santhony.gutierrez@amd.com } else if (q) { 141211593Santhony.gutierrez@amd.com return new NVrev16Q<uint8_t>(machInst, vd, vm); 141311593Santhony.gutierrez@amd.com } else { 141411593Santhony.gutierrez@amd.com return new NVrev16D<uint8_t>(machInst, vd, vm); 141511593Santhony.gutierrez@amd.com } 141611593Santhony.gutierrez@amd.com case 0x4: 141711593Santhony.gutierrez@amd.com return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 141811593Santhony.gutierrez@amd.com q, size, machInst, vd, vm); 141911593Santhony.gutierrez@amd.com case 0x5: 142011594Santhony.gutierrez@amd.com return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 142111593Santhony.gutierrez@amd.com q, size, machInst, vd, vm); 142211593Santhony.gutierrez@amd.com case 0x8: 142311593Santhony.gutierrez@amd.com return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 142411593Santhony.gutierrez@amd.com q, size, machInst, vd, vm); 142511385Sbrandon.potter@amd.com case 0x9: 142611385Sbrandon.potter@amd.com return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 142711385Sbrandon.potter@amd.com q, size, machInst, vd, vm); 142811385Sbrandon.potter@amd.com case 0xa: 142911385Sbrandon.potter@amd.com return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 143011385Sbrandon.potter@amd.com q, size, machInst, vd, vm); 143111385Sbrandon.potter@amd.com case 0xb: 143211385Sbrandon.potter@amd.com if (q) 143311385Sbrandon.potter@amd.com return new NVmvnQ<uint64_t>(machInst, vd, vm); 143411385Sbrandon.potter@amd.com else 143511385Sbrandon.potter@amd.com return new NVmvnD<uint64_t>(machInst, vd, vm); 143611385Sbrandon.potter@amd.com case 0xc: 143711385Sbrandon.potter@amd.com return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 143811385Sbrandon.potter@amd.com q, size, machInst, vd, vm); 143911385Sbrandon.potter@amd.com case 0xd: 144011385Sbrandon.potter@amd.com return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 1441378SN/A q, size, machInst, vd, vm); 1442360SN/A case 0xe: 14431450SN/A return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 14443114Sgblack@eecs.umich.edu q, size, machInst, vd, vm); 14452680Sktlim@umich.edu case 0xf: 1446360SN/A return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 14476701Sgblack@eecs.umich.edu q, size, machInst, vd, vm); 14486701Sgblack@eecs.umich.edu default: 14496701Sgblack@eecs.umich.edu return new Unknown(machInst); 1450360SN/A } 1451360SN/A case 0x1: 14522064SN/A switch (bits(b, 3, 1)) { 14535877Shsul@eecs.umich.edu case 0x0: 14542064SN/A if (bits(b, 4)) { 14558737Skoansin.tan@gmail.com if (q) { 14568737Skoansin.tan@gmail.com return new NVcgtQFp<float>(machInst, vd, vm); 14572064SN/A } else { 1458360SN/A return new NVcgtDFp<float>(machInst, vd, vm); 14595877Shsul@eecs.umich.edu } 14605877Shsul@eecs.umich.edu } else { 14615877Shsul@eecs.umich.edu return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 14628737Skoansin.tan@gmail.com q, size, machInst, vd, vm); 14638737Skoansin.tan@gmail.com } 14645877Shsul@eecs.umich.edu case 0x1: 14655877Shsul@eecs.umich.edu if (bits(b, 4)) { 14662064SN/A if (q) { 146710794Sbrandon.potter@amd.com return new NVcgeQFp<float>(machInst, vd, vm); 146810794Sbrandon.potter@amd.com } else { 14692064SN/A return new NVcgeDFp<float>(machInst, vd, vm); 1470360SN/A } 1471360SN/A } else { 14728706Sandreas.hansson@arm.com return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 14731458SN/A q, size, machInst, vd, vm); 1474360SN/A } 1475360SN/A case 0x2: 147610796Sbrandon.potter@amd.com if (bits(b, 4)) { 147710796Sbrandon.potter@amd.com if (q) { 147810796Sbrandon.potter@amd.com return new NVceqQFp<float>(machInst, vd, vm); 147910796Sbrandon.potter@amd.com } else { 148010796Sbrandon.potter@amd.com return new NVceqDFp<float>(machInst, vd, vm); 148110796Sbrandon.potter@amd.com } 148210796Sbrandon.potter@amd.com } else { 148310796Sbrandon.potter@amd.com return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 148410796Sbrandon.potter@amd.com q, size, machInst, vd, vm); 148510796Sbrandon.potter@amd.com } 148610796Sbrandon.potter@amd.com case 0x3: 148710796Sbrandon.potter@amd.com if (bits(b, 4)) { 148810796Sbrandon.potter@amd.com if (q) { 148910796Sbrandon.potter@amd.com return new NVcleQFp<float>(machInst, vd, vm); 149010796Sbrandon.potter@amd.com } else { 149110796Sbrandon.potter@amd.com return new NVcleDFp<float>(machInst, vd, vm); 149210796Sbrandon.potter@amd.com } 149310796Sbrandon.potter@amd.com } else { 149410796Sbrandon.potter@amd.com return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 149511337SMichael.Lebeane@amd.com q, size, machInst, vd, vm); 149611337SMichael.Lebeane@amd.com } 149711337SMichael.Lebeane@amd.com case 0x4: 149811337SMichael.Lebeane@amd.com if (bits(b, 4)) { 149911337SMichael.Lebeane@amd.com if (q) { 150011337SMichael.Lebeane@amd.com return new NVcltQFp<float>(machInst, vd, vm); 150111337SMichael.Lebeane@amd.com } else { 150211337SMichael.Lebeane@amd.com return new NVcltDFp<float>(machInst, vd, vm); 150311337SMichael.Lebeane@amd.com } 150411337SMichael.Lebeane@amd.com } else { 150511337SMichael.Lebeane@amd.com return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 150611337SMichael.Lebeane@amd.com q, size, machInst, vd, vm); 150711337SMichael.Lebeane@amd.com } 150811337SMichael.Lebeane@amd.com case 0x6: 150911337SMichael.Lebeane@amd.com if (bits(machInst, 10)) { 151011337SMichael.Lebeane@amd.com if (q) 151111337SMichael.Lebeane@amd.com return new NVabsQFp<float>(machInst, vd, vm); 1512378SN/A else 1513360SN/A return new NVabsDFp<float>(machInst, vd, vm); 15141450SN/A } else { 15153114Sgblack@eecs.umich.edu return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 15162680Sktlim@umich.edu q, size, machInst, vd, vm); 1517360SN/A } 15186701Sgblack@eecs.umich.edu case 0x7: 15196701Sgblack@eecs.umich.edu if (bits(machInst, 10)) { 1520360SN/A if (q) 152110796Sbrandon.potter@amd.com return new NVnegQFp<float>(machInst, vd, vm); 1522360SN/A else 15236109Ssanchezd@stanford.edu return new NVnegDFp<float>(machInst, vd, vm); 15246109Ssanchezd@stanford.edu } else { 1525360SN/A return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 15268706Sandreas.hansson@arm.com q, size, machInst, vd, vm); 1527360SN/A } 15281458SN/A } 1529360SN/A case 0x2: 1530360SN/A switch (bits(b, 4, 1)) { 1531360SN/A case 0x0: 15321999SN/A if (q) 15331999SN/A return new NVswpQ<uint64_t>(machInst, vd, vm); 15341999SN/A else 15353114Sgblack@eecs.umich.edu return new NVswpD<uint64_t>(machInst, vd, vm); 15362680Sktlim@umich.edu case 0x1: 15371999SN/A return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>( 15381999SN/A q, size, machInst, vd, vm); 15391999SN/A case 0x2: 15406701Sgblack@eecs.umich.edu return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 15418852Sandreas.hansson@arm.com q, size, machInst, vd, vm); 15426701Sgblack@eecs.umich.edu case 0x3: 15436701Sgblack@eecs.umich.edu return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 15446701Sgblack@eecs.umich.edu q, size, machInst, vd, vm); 15451999SN/A case 0x4: 15466701Sgblack@eecs.umich.edu if (b == 0x8) { 15476701Sgblack@eecs.umich.edu return decodeNeonUTwoMiscUSReg<NVmovn>( 15488706Sandreas.hansson@arm.com size, machInst, vd, vm); 15491999SN/A } else { 15501999SN/A return decodeNeonSTwoMiscUSReg<NVqmovuns>( 15511999SN/A size, machInst, vd, vm); 15521999SN/A } 15538737Skoansin.tan@gmail.com case 0x5: 15548737Skoansin.tan@gmail.com if (q) { 15551999SN/A return decodeNeonUTwoMiscUSReg<NVqmovun>( 15563669Sbinkertn@umich.edu size, machInst, vd, vm); 15573669Sbinkertn@umich.edu } else { 15583669Sbinkertn@umich.edu return decodeNeonSTwoMiscUSReg<NVqmovn>( 15593669Sbinkertn@umich.edu size, machInst, vd, vm); 15601999SN/A } 15611999SN/A case 0x6: 15621999SN/A if (b == 0xc) { 15631999SN/A const IntRegIndex vd = 15641999SN/A (IntRegIndex)(2 * (bits(machInst, 15, 12) | 15651999SN/A (bits(machInst, 22) << 4))); 15661999SN/A const IntRegIndex vm = 1567378SN/A (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1568360SN/A (bits(machInst, 5) << 4))); 15691450SN/A unsigned size = bits(machInst, 19, 18); 15703114Sgblack@eecs.umich.edu return decodeNeonSTwoShiftUSReg<NVshll>( 15712680Sktlim@umich.edu size, machInst, vd, vm, 8 << size); 1572360SN/A } else { 15736701Sgblack@eecs.umich.edu return new Unknown(machInst); 15746701Sgblack@eecs.umich.edu } 15756701Sgblack@eecs.umich.edu case 0xc: 1576360SN/A case 0xe: 15773670Sbinkertn@umich.edu if (b == 0x18) { 15783670Sbinkertn@umich.edu if (size != 1 || (vm % 2)) 1579360SN/A return new Unknown(machInst); 1580360SN/A return new NVcvts2h<uint16_t>(machInst, vd, vm); 1581360SN/A } else if (b == 0x1c) { 1582360SN/A if (size != 1 || (vd % 2)) 1583360SN/A return new Unknown(machInst); 1584360SN/A return new NVcvth2s<uint16_t>(machInst, vd, vm); 1585360SN/A } else { 1586360SN/A return new Unknown(machInst); 1587360SN/A } 1588360SN/A default: 1589360SN/A return new Unknown(machInst); 1590360SN/A } 1591360SN/A case 0x3: 1592360SN/A if (bits(b, 4, 3) == 0x3) { 1593360SN/A if ((q && (vd % 2 || vm % 2)) || size != 2) { 1594360SN/A return new Unknown(machInst); 1595360SN/A } else { 15963670Sbinkertn@umich.edu if (bits(b, 2)) { 15973670Sbinkertn@umich.edu if (bits(b, 1)) { 159810796Sbrandon.potter@amd.com if (q) { 15998737Skoansin.tan@gmail.com return new NVcvt2ufxQ<float>( 16008737Skoansin.tan@gmail.com machInst, vd, vm, 0); 16013670Sbinkertn@umich.edu } else { 16023670Sbinkertn@umich.edu return new NVcvt2ufxD<float>( 16033670Sbinkertn@umich.edu machInst, vd, vm, 0); 16043670Sbinkertn@umich.edu } 16053670Sbinkertn@umich.edu } else { 16063670Sbinkertn@umich.edu if (q) { 16073670Sbinkertn@umich.edu return new NVcvt2sfxQ<float>( 16083670Sbinkertn@umich.edu machInst, vd, vm, 0); 16093670Sbinkertn@umich.edu } else { 16103670Sbinkertn@umich.edu return new NVcvt2sfxD<float>( 16113670Sbinkertn@umich.edu machInst, vd, vm, 0); 16123670Sbinkertn@umich.edu } 16133670Sbinkertn@umich.edu } 16148706Sandreas.hansson@arm.com } else { 1615360SN/A if (bits(b, 1)) { 16161458SN/A if (q) { 1617360SN/A return new NVcvtu2fpQ<float>( 1618360SN/A machInst, vd, vm, 0); 16196683Stjones1@inf.ed.ac.uk } else { 16206683Stjones1@inf.ed.ac.uk return new NVcvtu2fpD<float>( 16216683Stjones1@inf.ed.ac.uk machInst, vd, vm, 0); 16226683Stjones1@inf.ed.ac.uk } 16236683Stjones1@inf.ed.ac.uk } else { 16246683Stjones1@inf.ed.ac.uk if (q) { 16256701Sgblack@eecs.umich.edu return new NVcvts2fpQ<float>( 16266701Sgblack@eecs.umich.edu machInst, vd, vm, 0); 16276683Stjones1@inf.ed.ac.uk } else { 16286683Stjones1@inf.ed.ac.uk return new NVcvts2fpD<float>( 16297823Ssteve.reinhardt@amd.com machInst, vd, vm, 0); 16306683Stjones1@inf.ed.ac.uk } 16316683Stjones1@inf.ed.ac.uk } 16326683Stjones1@inf.ed.ac.uk } 16336683Stjones1@inf.ed.ac.uk } 16346683Stjones1@inf.ed.ac.uk } else if ((b & 0x1a) == 0x10) { 16356683Stjones1@inf.ed.ac.uk if (bits(b, 2)) { 16368737Skoansin.tan@gmail.com if (q) { 16376683Stjones1@inf.ed.ac.uk return new NVrecpeQFp<float>(machInst, vd, vm); 16386683Stjones1@inf.ed.ac.uk } else { 16398706Sandreas.hansson@arm.com return new NVrecpeDFp<float>(machInst, vd, vm); 16406683Stjones1@inf.ed.ac.uk } 16416683Stjones1@inf.ed.ac.uk } else { 16426683Stjones1@inf.ed.ac.uk if (q) { 16436683Stjones1@inf.ed.ac.uk return new NVrecpeQ<uint32_t>(machInst, vd, vm); 16442553SN/A } else { 16456684Stjones1@inf.ed.ac.uk return new NVrecpeD<uint32_t>(machInst, vd, vm); 16466684Stjones1@inf.ed.ac.uk } 16476684Stjones1@inf.ed.ac.uk } 16486684Stjones1@inf.ed.ac.uk } else if ((b & 0x1a) == 0x12) { 16496684Stjones1@inf.ed.ac.uk if (bits(b, 2)) { 16506684Stjones1@inf.ed.ac.uk if (q) { 16516684Stjones1@inf.ed.ac.uk return new NVrsqrteQFp<float>(machInst, vd, vm); 165210796Sbrandon.potter@amd.com } else { 16536684Stjones1@inf.ed.ac.uk return new NVrsqrteDFp<float>(machInst, vd, vm); 16546684Stjones1@inf.ed.ac.uk } 16556701Sgblack@eecs.umich.edu } else { 16566701Sgblack@eecs.umich.edu if (q) { 165711321Ssteve.reinhardt@amd.com return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 16586684Stjones1@inf.ed.ac.uk } else { 16598737Skoansin.tan@gmail.com return new NVrsqrteD<uint32_t>(machInst, vd, vm); 16608852Sandreas.hansson@arm.com } 16618852Sandreas.hansson@arm.com } 16626684Stjones1@inf.ed.ac.uk } else { 16636684Stjones1@inf.ed.ac.uk return new Unknown(machInst); 16646684Stjones1@inf.ed.ac.uk } 16652553SN/A } 16662553SN/A return new Unknown(machInst); 16671354SN/A } 1668 1669 StaticInstPtr 1670 decodeNeonData(ExtMachInst machInst) 1671 { 1672 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1673 const uint32_t a = bits(machInst, 23, 19); 1674 const uint32_t b = bits(machInst, 11, 8); 1675 const uint32_t c = bits(machInst, 7, 4); 1676 if (bits(a, 4) == 0) { 1677 return decodeNeonThreeRegistersSameLength(machInst); 1678 } else if ((c & 0x9) == 1) { 1679 if ((a & 0x7) == 0) { 1680 return decodeNeonOneRegModImm(machInst); 1681 } else { 1682 return decodeNeonTwoRegAndShift(machInst); 1683 } 1684 } else if ((c & 0x9) == 9) { 1685 return decodeNeonTwoRegAndShift(machInst); 1686 } else if (bits(a, 2, 1) != 0x3) { 1687 if ((c & 0x5) == 0) { 1688 return decodeNeonThreeRegDiffLengths(machInst); 1689 } else if ((c & 0x5) == 4) { 1690 return decodeNeonTwoRegScalar(machInst); 1691 } 1692 } else if ((a & 0x16) == 0x16) { 1693 const IntRegIndex vd = 1694 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1695 (bits(machInst, 22) << 4))); 1696 const IntRegIndex vn = 1697 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1698 (bits(machInst, 7) << 4))); 1699 const IntRegIndex vm = 1700 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1701 (bits(machInst, 5) << 4))); 1702 if (!u) { 1703 if (bits(c, 0) == 0) { 1704 unsigned imm4 = bits(machInst, 11, 8); 1705 bool q = bits(machInst, 6); 1706 if (imm4 >= 16 && !q) 1707 return new Unknown(machInst); 1708 if (q) { 1709 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1710 } else { 1711 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1712 } 1713 } 1714 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1715 return decodeNeonTwoRegMisc(machInst); 1716 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { 1717 unsigned length = bits(machInst, 9, 8) + 1; 1718 if ((uint32_t)vn / 2 + length > 32) 1719 return new Unknown(machInst); 1720 if (bits(machInst, 6) == 0) { 1721 switch (length) { 1722 case 1: 1723 return new NVtbl1(machInst, vd, vn, vm); 1724 case 2: 1725 return new NVtbl2(machInst, vd, vn, vm); 1726 case 3: 1727 return new NVtbl3(machInst, vd, vn, vm); 1728 case 4: 1729 return new NVtbl4(machInst, vd, vn, vm); 1730 } 1731 } else { 1732 switch (length) { 1733 case 1: 1734 return new NVtbx1(machInst, vd, vn, vm); 1735 case 2: 1736 return new NVtbx2(machInst, vd, vn, vm); 1737 case 3: 1738 return new NVtbx3(machInst, vd, vn, vm); 1739 case 4: 1740 return new NVtbx4(machInst, vd, vn, vm); 1741 } 1742 } 1743 } else if (b == 0xc && (c & 0x9) == 0) { 1744 unsigned imm4 = bits(machInst, 19, 16); 1745 if (bits(imm4, 2, 0) == 0) 1746 return new Unknown(machInst); 1747 unsigned size = 0; 1748 while ((imm4 & 0x1) == 0) { 1749 size++; 1750 imm4 >>= 1; 1751 } 1752 unsigned index = imm4 >> 1; 1753 const bool q = bits(machInst, 6); 1754 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1755 q, size, machInst, vd, vm, index); 1756 } 1757 } 1758 return new Unknown(machInst); 1759 } 1760 ''' 1761}}; 1762 1763def format ThumbNeonMem() {{ 1764 decode_block = ''' 1765 return decodeNeonMem(machInst); 1766 ''' 1767}}; 1768 1769def format ThumbNeonData() {{ 1770 decode_block = ''' 1771 return decodeNeonData(machInst); 1772 ''' 1773}}; 1774 1775let {{ 1776 header_output = ''' 1777 StaticInstPtr 1778 decodeExtensionRegLoadStore(ExtMachInst machInst); 1779 ''' 1780 decoder_output = ''' 1781 StaticInstPtr 1782 decodeExtensionRegLoadStore(ExtMachInst machInst) 1783 { 1784 const uint32_t opcode = bits(machInst, 24, 20); 1785 const uint32_t offset = bits(machInst, 7, 0); 1786 const bool single = (bits(machInst, 8) == 0); 1787 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1788 RegIndex vd; 1789 if (single) { 1790 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1791 bits(machInst, 22)); 1792 } else { 1793 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1794 (bits(machInst, 22) << 5)); 1795 } 1796 switch (bits(opcode, 4, 3)) { 1797 case 0x0: 1798 if (bits(opcode, 4, 1) == 0x2 && 1799 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1800 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1801 if ((bits(machInst, 7, 4) & 0xd) != 1) { 1802 break; 1803 } 1804 const IntRegIndex rt = 1805 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1806 const IntRegIndex rt2 = 1807 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1808 const bool op = bits(machInst, 20); 1809 uint32_t vm; 1810 if (single) { 1811 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1812 } else { 1813 vm = (bits(machInst, 3, 0) << 1) | 1814 (bits(machInst, 5) << 5); 1815 } 1816 if (op) { 1817 return new Vmov2Core2Reg(machInst, rt, rt2, 1818 (IntRegIndex)vm); 1819 } else { 1820 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1821 rt, rt2); 1822 } 1823 } 1824 break; 1825 case 0x1: 1826 { 1827 if (offset == 0 || vd + offset/2 > NumFloatArchRegs) { 1828 break; 1829 } 1830 switch (bits(opcode, 1, 0)) { 1831 case 0x0: 1832 return new VLdmStm(machInst, rn, vd, single, 1833 true, false, false, offset); 1834 case 0x1: 1835 return new VLdmStm(machInst, rn, vd, single, 1836 true, false, true, offset); 1837 case 0x2: 1838 return new VLdmStm(machInst, rn, vd, single, 1839 true, true, false, offset); 1840 case 0x3: 1841 // If rn == sp, then this is called vpop. 1842 return new VLdmStm(machInst, rn, vd, single, 1843 true, true, true, offset); 1844 } 1845 } 1846 case 0x2: 1847 if (bits(opcode, 1, 0) == 0x2) { 1848 // If rn == sp, then this is called vpush. 1849 return new VLdmStm(machInst, rn, vd, single, 1850 false, true, false, offset); 1851 } else if (bits(opcode, 1, 0) == 0x3) { 1852 return new VLdmStm(machInst, rn, vd, single, 1853 false, true, true, offset); 1854 } 1855 // Fall through on purpose 1856 case 0x3: 1857 const bool up = (bits(machInst, 23) == 1); 1858 const uint32_t imm = bits(machInst, 7, 0) << 2; 1859 RegIndex vd; 1860 if (single) { 1861 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1862 (bits(machInst, 22))); 1863 } else { 1864 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1865 (bits(machInst, 22) << 5)); 1866 } 1867 if (bits(opcode, 1, 0) == 0x0) { 1868 if (single) { 1869 if (up) { 1870 return new %(vstr_us)s(machInst, vd, rn, up, imm); 1871 } else { 1872 return new %(vstr_s)s(machInst, vd, rn, up, imm); 1873 } 1874 } else { 1875 if (up) { 1876 return new %(vstr_ud)s(machInst, vd, vd + 1, 1877 rn, up, imm); 1878 } else { 1879 return new %(vstr_d)s(machInst, vd, vd + 1, 1880 rn, up, imm); 1881 } 1882 } 1883 } else if (bits(opcode, 1, 0) == 0x1) { 1884 if (single) { 1885 if (up) { 1886 return new %(vldr_us)s(machInst, vd, rn, up, imm); 1887 } else { 1888 return new %(vldr_s)s(machInst, vd, rn, up, imm); 1889 } 1890 } else { 1891 if (up) { 1892 return new %(vldr_ud)s(machInst, vd, vd + 1, 1893 rn, up, imm); 1894 } else { 1895 return new %(vldr_d)s(machInst, vd, vd + 1, 1896 rn, up, imm); 1897 } 1898 } 1899 } 1900 } 1901 return new Unknown(machInst); 1902 } 1903 ''' % { 1904 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 1905 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 1906 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 1907 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 1908 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 1909 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 1910 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 1911 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 1912 } 1913}}; 1914 1915def format ExtensionRegLoadStore() {{ 1916 decode_block = ''' 1917 return decodeExtensionRegLoadStore(machInst); 1918 ''' 1919}}; 1920 1921let {{ 1922 header_output = ''' 1923 StaticInstPtr 1924 decodeShortFpTransfer(ExtMachInst machInst); 1925 ''' 1926 decoder_output = ''' 1927 StaticInstPtr 1928 decodeShortFpTransfer(ExtMachInst machInst) 1929 { 1930 const uint32_t l = bits(machInst, 20); 1931 const uint32_t c = bits(machInst, 8); 1932 const uint32_t a = bits(machInst, 23, 21); 1933 const uint32_t b = bits(machInst, 6, 5); 1934 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 1935 (machInst.thumb == 0 && machInst.condCode == 0xf)) { 1936 return new Unknown(machInst); 1937 } 1938 if (l == 0 && c == 0) { 1939 if (a == 0) { 1940 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 1941 bits(machInst, 7); 1942 const IntRegIndex rt = 1943 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1944 if (bits(machInst, 20) == 1) { 1945 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 1946 } else { 1947 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 1948 } 1949 } else if (a == 0x7) { 1950 const IntRegIndex rt = 1951 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1952 uint32_t specReg = bits(machInst, 19, 16); 1953 switch (specReg) { 1954 case 0: 1955 specReg = MISCREG_FPSID; 1956 break; 1957 case 1: 1958 specReg = MISCREG_FPSCR; 1959 break; 1960 case 6: 1961 specReg = MISCREG_MVFR1; 1962 break; 1963 case 7: 1964 specReg = MISCREG_MVFR0; 1965 break; 1966 case 8: 1967 specReg = MISCREG_FPEXC; 1968 break; 1969 default: 1970 return new Unknown(machInst); 1971 } 1972 if (specReg == MISCREG_FPSCR) { 1973 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 1974 } else { 1975 return new Vmsr(machInst, (IntRegIndex)specReg, rt); 1976 } 1977 } 1978 } else if (l == 0 && c == 1) { 1979 if (bits(a, 2) == 0) { 1980 uint32_t vd = (bits(machInst, 7) << 5) | 1981 (bits(machInst, 19, 16) << 1); 1982 // Handle accessing each single precision half of the vector. 1983 vd += bits(machInst, 21); 1984 const IntRegIndex rt = 1985 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1986 if (bits(machInst, 22) == 1) { 1987 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 1988 rt, bits(machInst, 6, 5)); 1989 } else if (bits(machInst, 5) == 1) { 1990 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 1991 rt, bits(machInst, 6)); 1992 } else if (bits(machInst, 6) == 0) { 1993 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 1994 } else { 1995 return new Unknown(machInst); 1996 } 1997 } else if (bits(b, 1) == 0) { 1998 bool q = bits(machInst, 21); 1999 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2000 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2001 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2002 IntRegIndex rt = (IntRegIndex)(uint32_t) 2003 bits(machInst, 15, 12); 2004 if (q) { 2005 switch (be) { 2006 case 0: 2007 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2008 case 1: 2009 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2010 case 2: 2011 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2012 case 3: 2013 return new Unknown(machInst); 2014 } 2015 } else { 2016 switch (be) { 2017 case 0: 2018 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2019 case 1: 2020 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2021 case 2: 2022 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2023 case 3: 2024 return new Unknown(machInst); 2025 } 2026 } 2027 } 2028 } else if (l == 1 && c == 0) { 2029 if (a == 0) { 2030 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2031 bits(machInst, 7); 2032 const IntRegIndex rt = 2033 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2034 if (bits(machInst, 20) == 1) { 2035 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2036 } else { 2037 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2038 } 2039 } else if (a == 7) { 2040 const IntRegIndex rt = 2041 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2042 uint32_t specReg = bits(machInst, 19, 16); 2043 switch (specReg) { 2044 case 0: 2045 specReg = MISCREG_FPSID; 2046 break; 2047 case 1: 2048 specReg = MISCREG_FPSCR; 2049 break; 2050 case 6: 2051 specReg = MISCREG_MVFR1; 2052 break; 2053 case 7: 2054 specReg = MISCREG_MVFR0; 2055 break; 2056 case 8: 2057 specReg = MISCREG_FPEXC; 2058 break; 2059 default: 2060 return new Unknown(machInst); 2061 } 2062 if (rt == 0xf) { 2063 CPSR cpsrMask = 0; 2064 cpsrMask.n = 1; 2065 cpsrMask.z = 1; 2066 cpsrMask.c = 1; 2067 cpsrMask.v = 1; 2068 if (specReg == MISCREG_FPSCR) { 2069 return new VmrsApsrFpscr(machInst, INTREG_CONDCODES, 2070 (IntRegIndex)specReg, (uint32_t)cpsrMask); 2071 } else { 2072 return new VmrsApsr(machInst, INTREG_CONDCODES, 2073 (IntRegIndex)specReg, (uint32_t)cpsrMask); 2074 } 2075 } else if (specReg == MISCREG_FPSCR) { 2076 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2077 } else { 2078 return new Vmrs(machInst, rt, (IntRegIndex)specReg); 2079 } 2080 } 2081 } else { 2082 uint32_t vd = (bits(machInst, 7) << 5) | 2083 (bits(machInst, 19, 16) << 1); 2084 // Handle indexing into each single precision half of the vector. 2085 vd += bits(machInst, 21); 2086 uint32_t index; 2087 const IntRegIndex rt = 2088 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2089 const bool u = (bits(machInst, 23) == 1); 2090 if (bits(machInst, 22) == 1) { 2091 index = bits(machInst, 6, 5); 2092 if (u) { 2093 return new VmovRegCoreUB(machInst, rt, 2094 (IntRegIndex)vd, index); 2095 } else { 2096 return new VmovRegCoreSB(machInst, rt, 2097 (IntRegIndex)vd, index); 2098 } 2099 } else if (bits(machInst, 5) == 1) { 2100 index = bits(machInst, 6); 2101 if (u) { 2102 return new VmovRegCoreUH(machInst, rt, 2103 (IntRegIndex)vd, index); 2104 } else { 2105 return new VmovRegCoreSH(machInst, rt, 2106 (IntRegIndex)vd, index); 2107 } 2108 } else if (bits(machInst, 6) == 0 && !u) { 2109 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2110 } else { 2111 return new Unknown(machInst); 2112 } 2113 } 2114 return new Unknown(machInst); 2115 } 2116 ''' 2117}}; 2118 2119def format ShortFpTransfer() {{ 2120 decode_block = ''' 2121 return decodeShortFpTransfer(machInst); 2122 ''' 2123}}; 2124 2125let {{ 2126 header_output = ''' 2127 StaticInstPtr 2128 decodeVfpData(ExtMachInst machInst); 2129 ''' 2130 decoder_output = ''' 2131 StaticInstPtr 2132 decodeVfpData(ExtMachInst machInst) 2133 { 2134 const uint32_t opc1 = bits(machInst, 23, 20); 2135 const uint32_t opc2 = bits(machInst, 19, 16); 2136 const uint32_t opc3 = bits(machInst, 7, 6); 2137 //const uint32_t opc4 = bits(machInst, 3, 0); 2138 const bool single = (bits(machInst, 8) == 0); 2139 // Used to select between vcmp and vcmpe. 2140 const bool e = (bits(machInst, 7) == 1); 2141 IntRegIndex vd; 2142 IntRegIndex vm; 2143 IntRegIndex vn; 2144 if (single) { 2145 vd = (IntRegIndex)(bits(machInst, 22) | 2146 (bits(machInst, 15, 12) << 1)); 2147 vm = (IntRegIndex)(bits(machInst, 5) | 2148 (bits(machInst, 3, 0) << 1)); 2149 vn = (IntRegIndex)(bits(machInst, 7) | 2150 (bits(machInst, 19, 16) << 1)); 2151 } else { 2152 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2153 (bits(machInst, 15, 12) << 1)); 2154 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2155 (bits(machInst, 3, 0) << 1)); 2156 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2157 (bits(machInst, 19, 16) << 1)); 2158 } 2159 switch (opc1 & 0xb /* 1011 */) { 2160 case 0x0: 2161 if (bits(machInst, 6) == 0) { 2162 if (single) { 2163 return decodeVfpRegRegRegOp<VmlaS>( 2164 machInst, vd, vn, vm, false); 2165 } else { 2166 return decodeVfpRegRegRegOp<VmlaD>( 2167 machInst, vd, vn, vm, true); 2168 } 2169 } else { 2170 if (single) { 2171 return decodeVfpRegRegRegOp<VmlsS>( 2172 machInst, vd, vn, vm, false); 2173 } else { 2174 return decodeVfpRegRegRegOp<VmlsD>( 2175 machInst, vd, vn, vm, true); 2176 } 2177 } 2178 case 0x1: 2179 if (bits(machInst, 6) == 1) { 2180 if (single) { 2181 return decodeVfpRegRegRegOp<VnmlaS>( 2182 machInst, vd, vn, vm, false); 2183 } else { 2184 return decodeVfpRegRegRegOp<VnmlaD>( 2185 machInst, vd, vn, vm, true); 2186 } 2187 } else { 2188 if (single) { 2189 return decodeVfpRegRegRegOp<VnmlsS>( 2190 machInst, vd, vn, vm, false); 2191 } else { 2192 return decodeVfpRegRegRegOp<VnmlsD>( 2193 machInst, vd, vn, vm, true); 2194 } 2195 } 2196 case 0x2: 2197 if ((opc3 & 0x1) == 0) { 2198 if (single) { 2199 return decodeVfpRegRegRegOp<VmulS>( 2200 machInst, vd, vn, vm, false); 2201 } else { 2202 return decodeVfpRegRegRegOp<VmulD>( 2203 machInst, vd, vn, vm, true); 2204 } 2205 } else { 2206 if (single) { 2207 return decodeVfpRegRegRegOp<VnmulS>( 2208 machInst, vd, vn, vm, false); 2209 } else { 2210 return decodeVfpRegRegRegOp<VnmulD>( 2211 machInst, vd, vn, vm, true); 2212 } 2213 } 2214 case 0x3: 2215 if ((opc3 & 0x1) == 0) { 2216 if (single) { 2217 return decodeVfpRegRegRegOp<VaddS>( 2218 machInst, vd, vn, vm, false); 2219 } else { 2220 return decodeVfpRegRegRegOp<VaddD>( 2221 machInst, vd, vn, vm, true); 2222 } 2223 } else { 2224 if (single) { 2225 return decodeVfpRegRegRegOp<VsubS>( 2226 machInst, vd, vn, vm, false); 2227 } else { 2228 return decodeVfpRegRegRegOp<VsubD>( 2229 machInst, vd, vn, vm, true); 2230 } 2231 } 2232 case 0x8: 2233 if ((opc3 & 0x1) == 0) { 2234 if (single) { 2235 return decodeVfpRegRegRegOp<VdivS>( 2236 machInst, vd, vn, vm, false); 2237 } else { 2238 return decodeVfpRegRegRegOp<VdivD>( 2239 machInst, vd, vn, vm, true); 2240 } 2241 } 2242 break; 2243 case 0xb: 2244 if ((opc3 & 0x1) == 0) { 2245 const uint32_t baseImm = 2246 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2247 if (single) { 2248 uint32_t imm = vfp_modified_imm(baseImm, false); 2249 return decodeVfpRegImmOp<VmovImmS>( 2250 machInst, vd, imm, false); 2251 } else { 2252 uint64_t imm = vfp_modified_imm(baseImm, true); 2253 return decodeVfpRegImmOp<VmovImmD>( 2254 machInst, vd, imm, true); 2255 } 2256 } 2257 switch (opc2) { 2258 case 0x0: 2259 if (opc3 == 1) { 2260 if (single) { 2261 return decodeVfpRegRegOp<VmovRegS>( 2262 machInst, vd, vm, false); 2263 } else { 2264 return decodeVfpRegRegOp<VmovRegD>( 2265 machInst, vd, vm, true); 2266 } 2267 } else { 2268 if (single) { 2269 return decodeVfpRegRegOp<VabsS>( 2270 machInst, vd, vm, false); 2271 } else { 2272 return decodeVfpRegRegOp<VabsD>( 2273 machInst, vd, vm, true); 2274 } 2275 } 2276 case 0x1: 2277 if (opc3 == 1) { 2278 if (single) { 2279 return decodeVfpRegRegOp<VnegS>( 2280 machInst, vd, vm, false); 2281 } else { 2282 return decodeVfpRegRegOp<VnegD>( 2283 machInst, vd, vm, true); 2284 } 2285 } else { 2286 if (single) { 2287 return decodeVfpRegRegOp<VsqrtS>( 2288 machInst, vd, vm, false); 2289 } else { 2290 return decodeVfpRegRegOp<VsqrtD>( 2291 machInst, vd, vm, true); 2292 } 2293 } 2294 case 0x2: 2295 case 0x3: 2296 { 2297 const bool toHalf = bits(machInst, 16); 2298 const bool top = bits(machInst, 7); 2299 if (top) { 2300 if (toHalf) { 2301 return new VcvtFpSFpHT(machInst, vd, vm); 2302 } else { 2303 return new VcvtFpHTFpS(machInst, vd, vm); 2304 } 2305 } else { 2306 if (toHalf) { 2307 return new VcvtFpSFpHB(machInst, vd, vm); 2308 } else { 2309 return new VcvtFpHBFpS(machInst, vd, vm); 2310 } 2311 } 2312 } 2313 case 0x4: 2314 if (single) { 2315 if (e) { 2316 return new VcmpeS(machInst, vd, vm); 2317 } else { 2318 return new VcmpS(machInst, vd, vm); 2319 } 2320 } else { 2321 if (e) { 2322 return new VcmpeD(machInst, vd, vm); 2323 } else { 2324 return new VcmpD(machInst, vd, vm); 2325 } 2326 } 2327 case 0x5: 2328 if (single) { 2329 if (e) { 2330 return new VcmpeZeroS(machInst, vd, 0); 2331 } else { 2332 return new VcmpZeroS(machInst, vd, 0); 2333 } 2334 } else { 2335 if (e) { 2336 return new VcmpeZeroD(machInst, vd, 0); 2337 } else { 2338 return new VcmpZeroD(machInst, vd, 0); 2339 } 2340 } 2341 case 0x7: 2342 if (opc3 == 0x3) { 2343 if (single) { 2344 vm = (IntRegIndex)(bits(machInst, 5) | 2345 (bits(machInst, 3, 0) << 1)); 2346 return new VcvtFpSFpD(machInst, vd, vm); 2347 } else { 2348 vd = (IntRegIndex)(bits(machInst, 22) | 2349 (bits(machInst, 15, 12) << 1)); 2350 return new VcvtFpDFpS(machInst, vd, vm); 2351 } 2352 } 2353 break; 2354 case 0x8: 2355 if (bits(machInst, 7) == 0) { 2356 if (single) { 2357 return new VcvtUIntFpS(machInst, vd, vm); 2358 } else { 2359 vm = (IntRegIndex)(bits(machInst, 5) | 2360 (bits(machInst, 3, 0) << 1)); 2361 return new VcvtUIntFpD(machInst, vd, vm); 2362 } 2363 } else { 2364 if (single) { 2365 return new VcvtSIntFpS(machInst, vd, vm); 2366 } else { 2367 vm = (IntRegIndex)(bits(machInst, 5) | 2368 (bits(machInst, 3, 0) << 1)); 2369 return new VcvtSIntFpD(machInst, vd, vm); 2370 } 2371 } 2372 case 0xa: 2373 { 2374 const bool half = (bits(machInst, 7) == 0); 2375 const uint32_t imm = bits(machInst, 5) | 2376 (bits(machInst, 3, 0) << 1); 2377 const uint32_t size = 2378 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2379 if (single) { 2380 if (half) { 2381 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2382 } else { 2383 return new VcvtSFixedFpS(machInst, vd, vd, size); 2384 } 2385 } else { 2386 if (half) { 2387 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2388 } else { 2389 return new VcvtSFixedFpD(machInst, vd, vd, size); 2390 } 2391 } 2392 } 2393 case 0xb: 2394 { 2395 const bool half = (bits(machInst, 7) == 0); 2396 const uint32_t imm = bits(machInst, 5) | 2397 (bits(machInst, 3, 0) << 1); 2398 const uint32_t size = 2399 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2400 if (single) { 2401 if (half) { 2402 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2403 } else { 2404 return new VcvtUFixedFpS(machInst, vd, vd, size); 2405 } 2406 } else { 2407 if (half) { 2408 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2409 } else { 2410 return new VcvtUFixedFpD(machInst, vd, vd, size); 2411 } 2412 } 2413 } 2414 case 0xc: 2415 if (bits(machInst, 7) == 0) { 2416 if (single) { 2417 return new VcvtFpUIntSR(machInst, vd, vm); 2418 } else { 2419 vd = (IntRegIndex)(bits(machInst, 22) | 2420 (bits(machInst, 15, 12) << 1)); 2421 return new VcvtFpUIntDR(machInst, vd, vm); 2422 } 2423 } else { 2424 if (single) { 2425 return new VcvtFpUIntS(machInst, vd, vm); 2426 } else { 2427 vd = (IntRegIndex)(bits(machInst, 22) | 2428 (bits(machInst, 15, 12) << 1)); 2429 return new VcvtFpUIntD(machInst, vd, vm); 2430 } 2431 } 2432 case 0xd: 2433 if (bits(machInst, 7) == 0) { 2434 if (single) { 2435 return new VcvtFpSIntSR(machInst, vd, vm); 2436 } else { 2437 vd = (IntRegIndex)(bits(machInst, 22) | 2438 (bits(machInst, 15, 12) << 1)); 2439 return new VcvtFpSIntDR(machInst, vd, vm); 2440 } 2441 } else { 2442 if (single) { 2443 return new VcvtFpSIntS(machInst, vd, vm); 2444 } else { 2445 vd = (IntRegIndex)(bits(machInst, 22) | 2446 (bits(machInst, 15, 12) << 1)); 2447 return new VcvtFpSIntD(machInst, vd, vm); 2448 } 2449 } 2450 case 0xe: 2451 { 2452 const bool half = (bits(machInst, 7) == 0); 2453 const uint32_t imm = bits(machInst, 5) | 2454 (bits(machInst, 3, 0) << 1); 2455 const uint32_t size = 2456 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2457 if (single) { 2458 if (half) { 2459 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2460 } else { 2461 return new VcvtFpSFixedS(machInst, vd, vd, size); 2462 } 2463 } else { 2464 if (half) { 2465 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2466 } else { 2467 return new VcvtFpSFixedD(machInst, vd, vd, size); 2468 } 2469 } 2470 } 2471 case 0xf: 2472 { 2473 const bool half = (bits(machInst, 7) == 0); 2474 const uint32_t imm = bits(machInst, 5) | 2475 (bits(machInst, 3, 0) << 1); 2476 const uint32_t size = 2477 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2478 if (single) { 2479 if (half) { 2480 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2481 } else { 2482 return new VcvtFpUFixedS(machInst, vd, vd, size); 2483 } 2484 } else { 2485 if (half) { 2486 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2487 } else { 2488 return new VcvtFpUFixedD(machInst, vd, vd, size); 2489 } 2490 } 2491 } 2492 } 2493 break; 2494 } 2495 return new Unknown(machInst); 2496 } 2497 ''' 2498}}; 2499 2500def format VfpData() {{ 2501 decode_block = ''' 2502 return decodeVfpData(machInst); 2503 ''' 2504}}; 2505