1// -*- mode:c++ -*- 2 3// Copyright (c) 2010 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Copyright (c) 2007-2008 The Florida State University 16// All rights reserved. 17// 18// Redistribution and use in source and binary forms, with or without 19// modification, are permitted provided that the following conditions are 20// met: redistributions of source code must retain the above copyright 21// notice, this list of conditions and the following disclaimer; 22// redistributions in binary form must reproduce the above copyright 23// notice, this list of conditions and the following disclaimer in the 24// documentation and/or other materials provided with the distribution; 25// neither the name of the copyright holders nor the names of its 26// contributors may be used to endorse or promote products derived from 27// this software without specific prior written permission. 28// 29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40// 41// Authors: Stephen Hines 42 43//////////////////////////////////////////////////////////////////// 44// 45// Floating Point operate instructions 46// 47
| 1// -*- mode:c++ -*- 2 3// Copyright (c) 2010 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Copyright (c) 2007-2008 The Florida State University 16// All rights reserved. 17// 18// Redistribution and use in source and binary forms, with or without 19// modification, are permitted provided that the following conditions are 20// met: redistributions of source code must retain the above copyright 21// notice, this list of conditions and the following disclaimer; 22// redistributions in binary form must reproduce the above copyright 23// notice, this list of conditions and the following disclaimer in the 24// documentation and/or other materials provided with the distribution; 25// neither the name of the copyright holders nor the names of its 26// contributors may be used to endorse or promote products derived from 27// this software without specific prior written permission. 28// 29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40// 41// Authors: Stephen Hines 42 43//////////////////////////////////////////////////////////////////// 44// 45// Floating Point operate instructions 46// 47
|
| 48output header {{ 49 50 template<template <typename T> class Base> 51 StaticInstPtr 52 newNeonMemInst(const unsigned size, 53 const ExtMachInst &machInst, 54 const RegIndex dest, const RegIndex ra, 55 const uint32_t imm, const unsigned extraMemFlags) 56 { 57 switch (size) { 58 case 0: 59 return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags); 60 case 1: 61 return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags); 62 case 2: 63 return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags); 64 case 3: 65 return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags); 66 default: 67 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 68 } 69 } 70 71 template<template <typename T> class Base> 72 StaticInstPtr 73 newNeonMixInst(const unsigned size, 74 const ExtMachInst &machInst, 75 const RegIndex dest, const RegIndex op1, 76 const uint32_t step) 77 { 78 switch (size) { 79 case 0: 80 return new Base<uint8_t>(machInst, dest, op1, step); 81 case 1: 82 return new Base<uint16_t>(machInst, dest, op1, step); 83 case 2: 84 return new Base<uint32_t>(machInst, dest, op1, step); 85 case 3: 86 return new Base<uint64_t>(machInst, dest, op1, step); 87 default: 88 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 89 } 90 } 91 92}}; 93
|
48let {{ 49 header_output = ''' 50 StaticInstPtr 51 decodeNeonMem(ExtMachInst machInst); 52 53 StaticInstPtr 54 decodeNeonData(ExtMachInst machInst); 55 ''' 56 57 decoder_output = ''' 58 StaticInstPtr 59 decodeNeonMem(ExtMachInst machInst) 60 { 61 const uint32_t b = bits(machInst, 11, 8);
| 94let {{ 95 header_output = ''' 96 StaticInstPtr 97 decodeNeonMem(ExtMachInst machInst); 98 99 StaticInstPtr 100 decodeNeonData(ExtMachInst machInst); 101 ''' 102 103 decoder_output = ''' 104 StaticInstPtr 105 decodeNeonMem(ExtMachInst machInst) 106 { 107 const uint32_t b = bits(machInst, 11, 8);
|
62 const bool a = bits(machInst, 23); 63 const bool l = bits(machInst, 21);
| 108 const bool single = bits(machInst, 23); 109 const bool singleAll = single && (bits(b, 3, 2) == 3); 110 const bool load = bits(machInst, 21);
|
64
| 111
|
65 if (l) { 66 // Load instructions. 67 if (a) { 68 if (bits(b, 3, 2) != 3) { 69 switch (bits(b, 1, 0)) { 70 case 0x0: 71 return new WarnUnimplemented("vld1 single", machInst); 72 case 0x1: 73 return new WarnUnimplemented("vld2 single", machInst); 74 case 0x2: 75 return new WarnUnimplemented("vld3 single", machInst); 76 case 0x3: 77 return new WarnUnimplemented("vld4 single", machInst); 78 }
| 112 unsigned width = 0; 113 114 if (single) { 115 width = bits(b, 1, 0) + 1; 116 } else { 117 switch (bits(b, 3, 1)) { 118 case 0x0: width = 4; 119 break; 120 case 0x1: width = (b & 0x1) ? 2 : 1; 121 break; 122 case 0x2: width = 3; 123 break; 124 case 0x3: width = 1; 125 break; 126 case 0x4: width = 2; 127 break; 128 case 0x5: 129 if ((b & 0x1) == 0) { 130 width = 1; 131 break; 132 } 133 // Fall through on purpose. 134 default: 135 return new Unknown(machInst); 136 } 137 } 138 assert(width > 0 && width <= 4); 139 140 const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0); 141 const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16); 142 const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) | 143 bits(machInst, 22) << 4); 144 const uint32_t type = bits(machInst, 11, 8); 145 uint32_t size = 0; 146 uint32_t align = 0; 147 unsigned inc = 1; 148 unsigned regs = 1; 149 unsigned lane = 0; 150 if (single) { 151 if (singleAll) { 152 size = bits(machInst, 7, 6); 153 bool t = bits(machInst, 5); 154 unsigned eBytes = (1 << size); 155 align = (eBytes - 1) | TLB::AllowUnaligned; 156 if (width == 1) { 157 regs = t ? 2 : 1; 158 inc = 1;
|
79 } else {
| 159 } else {
|
80 switch (bits(b, 1, 0)) { 81 case 0x0: 82 return new WarnUnimplemented("vld1 single all", 83 machInst); 84 case 0x1: 85 return new WarnUnimplemented("vld2 single all", 86 machInst); 87 case 0x2: 88 return new WarnUnimplemented("vld3 single all", 89 machInst); 90 case 0x3: 91 return new WarnUnimplemented("vld4 single all", 92 machInst);
| 160 regs = width; 161 inc = t ? 2 : 1; 162 } 163 switch (width) { 164 case 1: 165 case 2: 166 if (bits(machInst, 4)) 167 align = width * eBytes - 1; 168 break; 169 case 3: 170 break; 171 case 4: 172 if (size == 3) { 173 if (bits(machInst, 4) == 0) 174 return new Unknown(machInst); 175 size = 2; 176 align = 0xf; 177 } else if (size == 2) { 178 if (bits(machInst, 4)) 179 align = 7; 180 } else { 181 if (bits(machInst, 4)) 182 align = 4 * eBytes - 1;
|
93 }
| 183 }
|
| 184 break;
|
94 } 95 } else {
| 185 } 186 } else {
|
96 switch (bits(b, 3, 1)) { 97 case 0x0: 98 return new WarnUnimplemented("vld4 multiple", machInst); 99 case 0x2: 100 return new WarnUnimplemented("vld3 multiple", machInst); 101 case 0x3: 102 return new WarnUnimplemented("vld1 multiple", machInst); 103 case 0x4: 104 return new WarnUnimplemented("vld2 multiple", machInst); 105 case 0x1: 106 if (b & 0x1) { 107 return new WarnUnimplemented("vld2 multiple", machInst); 108 } else { 109 return new WarnUnimplemented("vld1 multiple", machInst);
| 187 size = bits(machInst, 11, 10); 188 unsigned eBytes = (1 << size); 189 align = (eBytes - 1) | TLB::AllowUnaligned; 190 regs = width; 191 unsigned indexAlign = bits(machInst, 7, 4); 192 // If width is 1, inc is always 1. That's overridden later. 193 switch (size) { 194 case 0: 195 inc = 1; 196 lane = bits(indexAlign, 3, 1); 197 break; 198 case 1: 199 inc = bits(indexAlign, 1) ? 2 : 1; 200 lane = bits(indexAlign, 3, 2); 201 break; 202 case 2: 203 inc = bits(indexAlign, 2) ? 2 : 1; 204 lane = bits(indexAlign, 3); 205 break; 206 } 207 // Override inc for width of 1. 208 if (width == 1) { 209 inc = 1; 210 } 211 switch (width) { 212 case 1: 213 switch (size) { 214 case 0: 215 break; 216 case 1: 217 if (bits(indexAlign, 0)) 218 align = 1; 219 break; 220 case 2: 221 if (bits(indexAlign, 1, 0)) 222 align = 3; 223 break;
|
110 }
| 224 }
|
111 case 0x5: 112 if ((b & 0x1) == 0) { 113 return new WarnUnimplemented("vld1 multiple", machInst); 114 } else {
| 225 break; 226 case 2: 227 if (bits(indexAlign, 0)) 228 align = (2 * eBytes) - 1; 229 break; 230 case 3: 231 break; 232 case 4: 233 switch (size) { 234 case 0: 235 case 1: 236 if (bits(indexAlign, 0)) 237 align = (4 * eBytes) - 1;
|
115 break;
| 238 break;
|
| 239 case 2: 240 if (bits(indexAlign, 0)) 241 align = (4 << bits(indexAlign, 1, 0)) - 1; 242 break;
|
116 }
| 243 }
|
| 244 break;
|
117 } 118 }
| 245 } 246 }
|
| 247 if (size == 0x3) { 248 return new Unknown(machInst); 249 }
|
119 } else {
| 250 } else {
|
| 251 size = bits(machInst, 7, 6); 252 align = bits(machInst, 5, 4); 253 if (align == 0) { 254 // @align wasn't specified, so alignment can be turned off. 255 align = ((1 << size) - 1) | TLB::AllowUnaligned; 256 } else { 257 align = ((4 << align) - 1); 258 } 259 switch (width) { 260 case 1: 261 switch (type) { 262 case 0x7: regs = 1; 263 break; 264 case 0xa: regs = 2; 265 break; 266 case 0x6: regs = 3; 267 break; 268 case 0x2: regs = 4; 269 break; 270 default: 271 return new Unknown(machInst); 272 } 273 break; 274 case 2: 275 // Regs doesn't behave exactly as it does in the manual 276 // because they loop over regs registers twice and we break 277 // it down in the macroop. 278 switch (type) { 279 case 0x8: regs = 2; inc = 1; 280 break; 281 case 0x9: regs = 2; inc = 2; 282 break; 283 case 0x3: regs = 4; inc = 2; 284 break; 285 default: 286 return new Unknown(machInst); 287 } 288 break; 289 case 3: 290 regs = 3; 291 switch (type) { 292 case 0x4: inc = 1; 293 break; 294 case 0x5: inc = 2;; 295 break; 296 default: 297 return new Unknown(machInst); 298 } 299 break; 300 case 4: 301 regs = 4; 302 switch (type) { 303 case 0: inc = 1; 304 break; 305 case 1: inc = 2; 306 break; 307 default: 308 return new Unknown(machInst); 309 } 310 break; 311 } 312 } 313 314 if (load) { 315 // Load instructions. 316 if (single) { 317 return new VldSingle(machInst, singleAll, width, rn, vd, 318 regs, inc, size, align, rm, lane); 319 } else { 320 return new VldMult(machInst, width, rn, vd, 321 regs, inc, size, align, rm); 322 } 323 } else {
|
120 // Store instructions.
| 324 // Store instructions.
|
121 if (a) { 122 if (bits(b, 3, 2) != 3) { 123 switch (bits(b, 1, 0)) { 124 case 0x0: 125 return new WarnUnimplemented("vst1 single", machInst); 126 case 0x1: 127 return new WarnUnimplemented("vst2 single", machInst); 128 case 0x2: 129 return new WarnUnimplemented("vst3 single", machInst); 130 case 0x3: 131 return new WarnUnimplemented("vst4 single", machInst); 132 }
| 325 if (single) { 326 if (singleAll) { 327 return new Unknown(machInst);
|
133 } else {
| 328 } else {
|
134 switch (bits(b, 1, 0)) { 135 case 0x0: 136 return new WarnUnimplemented("vst1 single all", 137 machInst); 138 case 0x1: 139 return new WarnUnimplemented("vst2 single all", 140 machInst); 141 case 0x2: 142 return new WarnUnimplemented("vst3 single all", 143 machInst); 144 case 0x3: 145 return new WarnUnimplemented("vst4 single all", 146 machInst); 147 }
| 329 return new VstSingle(machInst, false, width, rn, vd, 330 regs, inc, size, align, rm, lane);
|
148 } 149 } else {
| 331 } 332 } else {
|
150 switch (bits(b, 3, 1)) { 151 case 0x0: 152 return new WarnUnimplemented("vst4 multiple", machInst); 153 case 0x2: 154 return new WarnUnimplemented("vst3 multiple", machInst); 155 case 0x3: 156 return new WarnUnimplemented("vst1 multiple", machInst); 157 case 0x4: 158 return new WarnUnimplemented("vst2 multiple", machInst); 159 case 0x1: 160 if (b & 0x1) { 161 return new WarnUnimplemented("vst2 multiple", machInst); 162 } else { 163 return new WarnUnimplemented("vst1 multiple", machInst); 164 } 165 case 0x5: 166 if ((b & 0x1) == 0) { 167 return new WarnUnimplemented("vst1 multiple", machInst); 168 } else { 169 break; 170 } 171 }
| 333 return new VstMult(machInst, width, rn, vd, 334 regs, inc, size, align, rm);
|
172 } 173 } 174 return new Unknown(machInst); 175 } 176 ''' 177 178 decoder_output += ''' 179 static StaticInstPtr 180 decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 181 { 182 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 183 const uint32_t a = bits(machInst, 11, 8); 184 const bool b = bits(machInst, 4); 185 const uint32_t c = bits(machInst, 21, 20);
| 335 } 336 } 337 return new Unknown(machInst); 338 } 339 ''' 340 341 decoder_output += ''' 342 static StaticInstPtr 343 decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 344 { 345 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 346 const uint32_t a = bits(machInst, 11, 8); 347 const bool b = bits(machInst, 4); 348 const uint32_t c = bits(machInst, 21, 20);
|
| 349 const IntRegIndex vd = 350 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 351 (bits(machInst, 22) << 4))); 352 const IntRegIndex vn = 353 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 354 (bits(machInst, 7) << 4))); 355 const IntRegIndex vm = 356 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 357 (bits(machInst, 5) << 4))); 358 const unsigned size = bits(machInst, 21, 20); 359 const bool q = bits(machInst, 6); 360 if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1))) 361 return new Unknown(machInst);
|
186 switch (a) { 187 case 0x0: 188 if (b) {
| 362 switch (a) { 363 case 0x0: 364 if (b) {
|
189 if (bits(machInst, 9) == 0) { 190 return new WarnUnimplemented("vhadd", machInst);
| 365 if (u) { 366 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 367 q, size, machInst, vd, vn, vm);
|
191 } else {
| 368 } else {
|
192 return new WarnUnimplemented("vhsub", machInst);
| 369 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>( 370 q, size, machInst, vd, vn, vm);
|
193 } 194 } else {
| 371 } 372 } else {
|
195 return new WarnUnimplemented("vqadd", machInst);
| 373 if (size == 3) 374 return new Unknown(machInst); 375 return decodeNeonUSThreeReg<VhaddD, VhaddQ>( 376 q, u, size, machInst, vd, vn, vm);
|
196 } 197 case 0x1: 198 if (!b) {
| 377 } 378 case 0x1: 379 if (!b) {
|
199 return new WarnUnimplemented("vrhadd", machInst);
| 380 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>( 381 q, u, size, machInst, vd, vn, vm);
|
200 } else { 201 if (u) { 202 switch (c) { 203 case 0:
| 382 } else { 383 if (u) { 384 switch (c) { 385 case 0:
|
204 return new WarnUnimplemented("veor", machInst);
| 386 if (q) { 387 return new VeorQ<uint64_t>(machInst, vd, vn, vm); 388 } else { 389 return new VeorD<uint64_t>(machInst, vd, vn, vm); 390 }
|
205 case 1:
| 391 case 1:
|
206 return new WarnUnimplemented("vbsl", machInst);
| 392 if (q) { 393 return new VbslQ<uint64_t>(machInst, vd, vn, vm); 394 } else { 395 return new VbslD<uint64_t>(machInst, vd, vn, vm); 396 }
|
207 case 2:
| 397 case 2:
|
208 return new WarnUnimplemented("vbit", machInst);
| 398 if (q) { 399 return new VbitQ<uint64_t>(machInst, vd, vn, vm); 400 } else { 401 return new VbitD<uint64_t>(machInst, vd, vn, vm); 402 }
|
209 case 3:
| 403 case 3:
|
210 return new WarnUnimplemented("vbif", machInst);
| 404 if (q) { 405 return new VbifQ<uint64_t>(machInst, vd, vn, vm); 406 } else { 407 return new VbifD<uint64_t>(machInst, vd, vn, vm); 408 }
|
211 } 212 } else { 213 switch (c) { 214 case 0:
| 409 } 410 } else { 411 switch (c) { 412 case 0:
|
215 return new WarnUnimplemented("vand (reg)", machInst);
| 413 if (q) { 414 return new VandQ<uint64_t>(machInst, vd, vn, vm); 415 } else { 416 return new VandD<uint64_t>(machInst, vd, vn, vm); 417 }
|
216 case 1:
| 418 case 1:
|
217 return new WarnUnimplemented("vbic (reg)", machInst);
| 419 if (q) { 420 return new VbicQ<uint64_t>(machInst, vd, vn, vm); 421 } else { 422 return new VbicD<uint64_t>(machInst, vd, vn, vm); 423 }
|
218 case 2:
| 424 case 2:
|
219 { 220 const IntRegIndex n = (IntRegIndex)( 221 (uint32_t)bits(machInst, 19, 16) | 222 (uint32_t)(bits(machInst, 7) << 4)); 223 const IntRegIndex m = (IntRegIndex)( 224 (uint32_t)bits(machInst, 3, 0) | 225 (uint32_t)(bits(machInst, 5) << 4)); 226 if (n == m) { 227 return new WarnUnimplemented("vmov (reg)", 228 machInst);
| 425 if (vn == vm) { 426 if (q) { 427 return new VmovQ<uint64_t>( 428 machInst, vd, vn, vm);
|
229 } else {
| 429 } else {
|
230 return new WarnUnimplemented("vorr (reg)", 231 machInst);
| 430 return new VmovD<uint64_t>( 431 machInst, vd, vn, vm);
|
232 }
| 432 }
|
| 433 } else { 434 if (q) { 435 return new VorrQ<uint64_t>( 436 machInst, vd, vn, vm); 437 } else { 438 return new VorrD<uint64_t>( 439 machInst, vd, vn, vm); 440 }
|
233 } 234 case 3:
| 441 } 442 case 3:
|
235 return new WarnUnimplemented("vorn (reg)", machInst);
| 443 if (q) { 444 return new VornQ<uint64_t>( 445 machInst, vd, vn, vm); 446 } else { 447 return new VornD<uint64_t>( 448 machInst, vd, vn, vm); 449 }
|
236 } 237 } 238 } 239 case 0x2: 240 if (b) {
| 450 } 451 } 452 } 453 case 0x2: 454 if (b) {
|
241 return new WarnUnimplemented("vqsub", machInst); 242 } else { 243 if (bits(machInst, 9) == 0) { 244 return new WarnUnimplemented("vhadd", machInst);
| 455 if (u) { 456 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 457 q, size, machInst, vd, vn, vm);
|
245 } else {
| 458 } else {
|
246 return new WarnUnimplemented("vhsub", machInst);
| 459 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 460 q, size, machInst, vd, vn, vm);
|
247 }
| 461 }
|
| 462 } else { 463 if (size == 3) 464 return new Unknown(machInst); 465 return decodeNeonUSThreeReg<VhsubD, VhsubQ>( 466 q, u, size, machInst, vd, vn, vm);
|
248 } 249 case 0x3: 250 if (b) {
| 467 } 468 case 0x3: 469 if (b) {
|
251 return new WarnUnimplemented("vcge (reg)", machInst);
| 470 return decodeNeonUSThreeReg<VcgeD, VcgeQ>( 471 q, u, size, machInst, vd, vn, vm);
|
252 } else {
| 472 } else {
|
253 return new WarnUnimplemented("vcgt (reg)", machInst);
| 473 return decodeNeonUSThreeReg<VcgtD, VcgtQ>( 474 q, u, size, machInst, vd, vn, vm);
|
254 } 255 case 0x4: 256 if (b) {
| 475 } 476 case 0x4: 477 if (b) {
|
257 return new WarnUnimplemented("vqshl (reg)", machInst);
| 478 if (u) { 479 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>( 480 q, size, machInst, vd, vm, vn); 481 } else { 482 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>( 483 q, size, machInst, vd, vm, vn); 484 }
|
258 } else {
| 485 } else {
|
259 return new WarnUnimplemented("vshl (reg)", machInst);
| 486 return decodeNeonUSThreeReg<VshlD, VshlQ>( 487 q, u, size, machInst, vd, vm, vn);
|
260 } 261 case 0x5: 262 if (b) {
| 488 } 489 case 0x5: 490 if (b) {
|
263 return new WarnUnimplemented("vqrshl", machInst);
| 491 if (u) { 492 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>( 493 q, size, machInst, vd, vm, vn); 494 } else { 495 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>( 496 q, size, machInst, vd, vm, vn); 497 }
|
264 } else {
| 498 } else {
|
265 return new WarnUnimplemented("vrshl", machInst);
| 499 return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 500 q, u, size, machInst, vd, vm, vn);
|
266 } 267 case 0x6: 268 if (b) {
| 501 } 502 case 0x6: 503 if (b) {
|
269 return new WarnUnimplemented("vmin (int)", machInst);
| 504 return decodeNeonUSThreeReg<VminD, VminQ>( 505 q, u, size, machInst, vd, vn, vm);
|
270 } else {
| 506 } else {
|
271 return new WarnUnimplemented("vmax (int)", machInst);
| 507 return decodeNeonUSThreeReg<VmaxD, VmaxQ>( 508 q, u, size, machInst, vd, vn, vm);
|
272 } 273 case 0x7: 274 if (b) {
| 509 } 510 case 0x7: 511 if (b) {
|
275 return new WarnUnimplemented("vaba", machInst);
| 512 return decodeNeonUSThreeReg<VabaD, VabaQ>( 513 q, u, size, machInst, vd, vn, vm);
|
276 } else { 277 if (bits(machInst, 23) == 1) {
| 514 } else { 515 if (bits(machInst, 23) == 1) {
|
278 if (bits(machInst, 6) == 1) {
| 516 if (q) {
|
279 return new Unknown(machInst); 280 } else {
| 517 return new Unknown(machInst); 518 } else {
|
281 return new WarnUnimplemented("vabdl (int)", machInst);
| 519 return decodeNeonUSThreeUSReg<Vabdl>( 520 u, size, machInst, vd, vn, vm);
|
282 } 283 } else {
| 521 } 522 } else {
|
284 return new WarnUnimplemented("vabd (int)", machInst);
| 523 return decodeNeonUSThreeReg<VabdD, VabdQ>( 524 q, u, size, machInst, vd, vn, vm);
|
285 } 286 } 287 case 0x8: 288 if (b) { 289 if (u) {
| 525 } 526 } 527 case 0x8: 528 if (b) { 529 if (u) {
|
290 return new WarnUnimplemented("vceq (reg)", machInst);
| 530 return decodeNeonUThreeReg<VceqD, VceqQ>( 531 q, size, machInst, vd, vn, vm);
|
291 } else {
| 532 } else {
|
292 return new WarnUnimplemented("vtst", machInst);
| 533 return decodeNeonUThreeReg<VtstD, VtstQ>( 534 q, size, machInst, vd, vn, vm);
|
293 } 294 } else { 295 if (u) {
| 535 } 536 } else { 537 if (u) {
|
296 return new WarnUnimplemented("vsub (int)", machInst);
| 538 return decodeNeonUThreeReg<NVsubD, NVsubQ>( 539 q, size, machInst, vd, vn, vm);
|
297 } else {
| 540 } else {
|
298 return new WarnUnimplemented("vadd (int)", machInst);
| 541 return decodeNeonUThreeReg<NVaddD, NVaddQ>( 542 q, size, machInst, vd, vn, vm);
|
299 } 300 } 301 case 0x9: 302 if (b) { 303 if (u) {
| 543 } 544 } 545 case 0x9: 546 if (b) { 547 if (u) {
|
304 return new WarnUnimplemented("vmul (poly)", machInst);
| 548 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 549 q, size, machInst, vd, vn, vm);
|
305 } else {
| 550 } else {
|
306 return new WarnUnimplemented("vmul (int)", machInst);
| 551 return decodeNeonSThreeReg<NVmulD, NVmulQ>( 552 q, size, machInst, vd, vn, vm);
|
307 } 308 } else { 309 if (u) {
| 553 } 554 } else { 555 if (u) {
|
310 return new WarnUnimplemented("vmls (int)", machInst);
| 556 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 557 q, u, size, machInst, vd, vn, vm);
|
311 } else {
| 558 } else {
|
312 return new WarnUnimplemented("vmla (int)", machInst);
| 559 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 560 q, u, size, machInst, vd, vn, vm);
|
313 } 314 } 315 case 0xa: 316 if (b) {
| 561 } 562 } 563 case 0xa: 564 if (b) {
|
317 return new WarnUnimplemented("vpmin (int)", machInst);
| 565 return decodeNeonUSThreeReg<VpminD, VpminQ>( 566 q, u, size, machInst, vd, vn, vm);
|
318 } else {
| 567 } else {
|
319 return new WarnUnimplemented("vpmax (int)", machInst);
| 568 return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>( 569 q, u, size, machInst, vd, vn, vm);
|
320 } 321 case 0xb: 322 if (b) { 323 if (u) { 324 return new Unknown(machInst); 325 } else {
| 570 } 571 case 0xb: 572 if (b) { 573 if (u) { 574 return new Unknown(machInst); 575 } else {
|
326 return new WarnUnimplemented("vpadd (int)", machInst);
| 576 return decodeNeonUThreeReg<NVpaddD, NVpaddQ>( 577 q, size, machInst, vd, vn, vm);
|
327 } 328 } else { 329 if (u) {
| 578 } 579 } else { 580 if (u) {
|
330 return new WarnUnimplemented("vqrdmulh", machInst);
| 581 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>( 582 q, size, machInst, vd, vn, vm);
|
331 } else {
| 583 } else {
|
332 return new WarnUnimplemented("vqdmulh", machInst);
| 584 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>( 585 q, size, machInst, vd, vn, vm);
|
333 } 334 } 335 case 0xc: 336 return new Unknown(machInst); 337 case 0xd: 338 if (b) { 339 if (u) { 340 if (bits(c, 1) == 0) {
| 586 } 587 } 588 case 0xc: 589 return new Unknown(machInst); 590 case 0xd: 591 if (b) { 592 if (u) { 593 if (bits(c, 1) == 0) {
|
341 return new WarnUnimplemented("vmul (fp)", machInst);
| 594 if (q) { 595 return new NVmulQFp<float>(machInst, vd, vn, vm); 596 } else { 597 return new NVmulDFp<float>(machInst, vd, vn, vm); 598 }
|
342 } else { 343 return new Unknown(machInst); 344 } 345 } else { 346 if (bits(c, 1) == 0) {
| 599 } else { 600 return new Unknown(machInst); 601 } 602 } else { 603 if (bits(c, 1) == 0) {
|
347 return new WarnUnimplemented("vmla (fp)", machInst);
| 604 if (q) { 605 return new NVmlaQFp<float>(machInst, vd, vn, vm); 606 } else { 607 return new NVmlaDFp<float>(machInst, vd, vn, vm); 608 }
|
348 } else {
| 609 } else {
|
349 return new WarnUnimplemented("vmls (fp)", machInst);
| 610 if (q) { 611 return new NVmlsQFp<float>(machInst, vd, vn, vm); 612 } else { 613 return new NVmlsDFp<float>(machInst, vd, vn, vm); 614 }
|
350 } 351 } 352 } else { 353 if (u) { 354 if (bits(c, 1) == 0) {
| 615 } 616 } 617 } else { 618 if (u) { 619 if (bits(c, 1) == 0) {
|
355 return new WarnUnimplemented("vpadd (fp)", machInst);
| 620 if (q) { 621 return new VpaddQFp<float>(machInst, vd, vn, vm); 622 } else { 623 return new VpaddDFp<float>(machInst, vd, vn, vm); 624 }
|
356 } else {
| 625 } else {
|
357 return new WarnUnimplemented("vabd (fp)", machInst);
| 626 if (q) { 627 return new VabdQFp<float>(machInst, vd, vn, vm); 628 } else { 629 return new VabdDFp<float>(machInst, vd, vn, vm); 630 }
|
358 } 359 } else { 360 if (bits(c, 1) == 0) {
| 631 } 632 } else { 633 if (bits(c, 1) == 0) {
|
361 return new WarnUnimplemented("vadd (fp)", machInst);
| 634 if (q) { 635 return new VaddQFp<float>(machInst, vd, vn, vm); 636 } else { 637 return new VaddDFp<float>(machInst, vd, vn, vm); 638 }
|
362 } else {
| 639 } else {
|
363 return new WarnUnimplemented("vsub (fp)", machInst);
| 640 if (q) { 641 return new VsubQFp<float>(machInst, vd, vn, vm); 642 } else { 643 return new VsubDFp<float>(machInst, vd, vn, vm); 644 }
|
364 } 365 } 366 } 367 case 0xe: 368 if (b) { 369 if (u) { 370 if (bits(c, 1) == 0) {
| 645 } 646 } 647 } 648 case 0xe: 649 if (b) { 650 if (u) { 651 if (bits(c, 1) == 0) {
|
371 return new WarnUnimplemented("vacge", machInst);
| 652 if (q) { 653 return new VacgeQFp<float>(machInst, vd, vn, vm); 654 } else { 655 return new VacgeDFp<float>(machInst, vd, vn, vm); 656 }
|
372 } else {
| 657 } else {
|
373 return new WarnUnimplemented("vacgt", machInst);
| 658 if (q) { 659 return new VacgtQFp<float>(machInst, vd, vn, vm); 660 } else { 661 return new VacgtDFp<float>(machInst, vd, vn, vm); 662 }
|
374 } 375 } else { 376 return new Unknown(machInst); 377 } 378 } else { 379 if (u) { 380 if (bits(c, 1) == 0) {
| 663 } 664 } else { 665 return new Unknown(machInst); 666 } 667 } else { 668 if (u) { 669 if (bits(c, 1) == 0) {
|
381 return new WarnUnimplemented("vcge (reg)", machInst);
| 670 if (q) { 671 return new VcgeQFp<float>(machInst, vd, vn, vm); 672 } else { 673 return new VcgeDFp<float>(machInst, vd, vn, vm); 674 }
|
382 } else {
| 675 } else {
|
383 return new WarnUnimplemented("vcgt (reg)", machInst);
| 676 if (q) { 677 return new VcgtQFp<float>(machInst, vd, vn, vm); 678 } else { 679 return new VcgtDFp<float>(machInst, vd, vn, vm); 680 }
|
384 } 385 } else { 386 if (bits(c, 1) == 0) {
| 681 } 682 } else { 683 if (bits(c, 1) == 0) {
|
387 return new WarnUnimplemented("vceq (reg)", machInst);
| 684 if (q) { 685 return new VceqQFp<float>(machInst, vd, vn, vm); 686 } else { 687 return new VceqDFp<float>(machInst, vd, vn, vm); 688 }
|
388 } else { 389 return new Unknown(machInst); 390 } 391 } 392 } 393 case 0xf: 394 if (b) { 395 if (u) { 396 return new Unknown(machInst); 397 } else { 398 if (bits(c, 1) == 0) {
| 689 } else { 690 return new Unknown(machInst); 691 } 692 } 693 } 694 case 0xf: 695 if (b) { 696 if (u) { 697 return new Unknown(machInst); 698 } else { 699 if (bits(c, 1) == 0) {
|
399 return new WarnUnimplemented("vrecps", machInst);
| 700 if (q) { 701 return new VrecpsQFp<float>(machInst, vd, vn, vm); 702 } else { 703 return new VrecpsDFp<float>(machInst, vd, vn, vm); 704 }
|
400 } else {
| 705 } else {
|
401 return new WarnUnimplemented("vrsqrts", machInst);
| 706 if (q) { 707 return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 708 } else { 709 return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 710 }
|
402 } 403 } 404 } else { 405 if (u) { 406 if (bits(c, 1) == 0) {
| 711 } 712 } 713 } else { 714 if (u) { 715 if (bits(c, 1) == 0) {
|
407 return new WarnUnimplemented("vpmax (fp)", machInst);
| 716 if (q) { 717 return new VpmaxQFp<float>(machInst, vd, vn, vm); 718 } else { 719 return new VpmaxDFp<float>(machInst, vd, vn, vm); 720 }
|
408 } else {
| 721 } else {
|
409 return new WarnUnimplemented("vpmin (fp)", machInst);
| 722 if (q) { 723 return new VpminQFp<float>(machInst, vd, vn, vm); 724 } else { 725 return new VpminDFp<float>(machInst, vd, vn, vm); 726 }
|
410 } 411 } else { 412 if (bits(c, 1) == 0) {
| 727 } 728 } else { 729 if (bits(c, 1) == 0) {
|
413 return new WarnUnimplemented("vmax (fp)", machInst);
| 730 if (q) { 731 return new VmaxQFp<float>(machInst, vd, vn, vm); 732 } else { 733 return new VmaxDFp<float>(machInst, vd, vn, vm); 734 }
|
414 } else {
| 735 } else {
|
415 return new WarnUnimplemented("vmin (fp)", machInst);
| 736 if (q) { 737 return new VminQFp<float>(machInst, vd, vn, vm); 738 } else { 739 return new VminDFp<float>(machInst, vd, vn, vm); 740 }
|
416 } 417 } 418 } 419 } 420 return new Unknown(machInst); 421 } 422 423 static StaticInstPtr 424 decodeNeonOneRegModImm(ExtMachInst machInst) 425 {
| 741 } 742 } 743 } 744 } 745 return new Unknown(machInst); 746 } 747 748 static StaticInstPtr 749 decodeNeonOneRegModImm(ExtMachInst machInst) 750 {
|
| 751 const IntRegIndex vd = 752 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 753 (bits(machInst, 22) << 4))); 754 const bool q = bits(machInst, 6);
|
426 const bool op = bits(machInst, 5);
| 755 const bool op = bits(machInst, 5);
|
427 const uint32_t cmode = bits(machInst, 11, 8);
| 756 const uint8_t cmode = bits(machInst, 11, 8); 757 const uint8_t imm = ((THUMB ? bits(machInst, 28) : 758 bits(machInst, 24)) << 7) | 759 (bits(machInst, 18, 16) << 4) | 760 (bits(machInst, 3, 0) << 0); 761 const uint64_t bigImm = simd_modified_imm(op, cmode, imm);
|
428 if (op) { 429 if (bits(cmode, 3) == 0) { 430 if (bits(cmode, 0) == 0) {
| 762 if (op) { 763 if (bits(cmode, 3) == 0) { 764 if (bits(cmode, 0) == 0) {
|
431 return new WarnUnimplemented("vmov (imm)", machInst);
| 765 if (q) 766 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 767 else 768 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
|
432 } else {
| 769 } else {
|
433 return new WarnUnimplemented("vorr (imm)", machInst);
| 770 if (q) 771 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 772 else 773 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
|
434 } 435 } else { 436 if (bits(cmode, 2) == 1) {
| 774 } 775 } else { 776 if (bits(cmode, 2) == 1) {
|
437 return new WarnUnimplemented("vmov (imm)", machInst);
| 777 switch (bits(cmode, 1, 0)) { 778 case 0: 779 case 1: 780 if (q) 781 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 782 else 783 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 784 case 2: 785 if (q) 786 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 787 else 788 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 789 case 3: 790 if (q) 791 return new Unknown(machInst); 792 else 793 return new Unknown(machInst); 794 }
|
438 } else { 439 if (bits(cmode, 0) == 0) {
| 795 } else { 796 if (bits(cmode, 0) == 0) {
|
440 return new WarnUnimplemented("vmov (imm)", machInst);
| 797 if (q) 798 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 799 else 800 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
|
441 } else {
| 801 } else {
|
442 return new WarnUnimplemented("vorr (imm)", machInst);
| 802 if (q) 803 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 804 else 805 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
|
443 } 444 } 445 } 446 } else { 447 if (bits(cmode, 3) == 0) { 448 if (bits(cmode, 0) == 0) {
| 806 } 807 } 808 } 809 } else { 810 if (bits(cmode, 3) == 0) { 811 if (bits(cmode, 0) == 0) {
|
449 return new WarnUnimplemented("vmvn (imm)", machInst);
| 812 if (q) 813 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 814 else 815 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
|
450 } else {
| 816 } else {
|
451 return new WarnUnimplemented("vbic (imm)", machInst);
| 817 if (q) 818 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 819 else 820 return new NVorriD<uint64_t>(machInst, vd, bigImm);
|
452 } 453 } else { 454 if (bits(cmode, 2) == 1) {
| 821 } 822 } else { 823 if (bits(cmode, 2) == 1) {
|
455 switch (bits(cmode, 1, 0)) { 456 case 0: 457 case 1: 458 return new WarnUnimplemented("vmvn (imm)", machInst); 459 case 2: 460 return new WarnUnimplemented("vmov (imm)", machInst); 461 case 3: 462 return new Unknown(machInst); 463 } 464 return new WarnUnimplemented("vmov (imm)", machInst);
| 824 if (q) 825 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 826 else 827 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
|
465 } else { 466 if (bits(cmode, 0) == 0) {
| 828 } else { 829 if (bits(cmode, 0) == 0) {
|
467 return new WarnUnimplemented("vmvn (imm)", machInst);
| 830 if (q) 831 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 832 else 833 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
|
468 } else {
| 834 } else {
|
469 return new WarnUnimplemented("vbic (imm)", machInst);
| 835 if (q) 836 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 837 else 838 return new NVorriD<uint64_t>(machInst, vd, bigImm);
|
470 } 471 } 472 } 473 } 474 return new Unknown(machInst); 475 } 476 477 static StaticInstPtr 478 decodeNeonTwoRegAndShift(ExtMachInst machInst) 479 { 480 const uint32_t a = bits(machInst, 11, 8); 481 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 482 const bool b = bits(machInst, 6); 483 const bool l = bits(machInst, 7);
| 839 } 840 } 841 } 842 } 843 return new Unknown(machInst); 844 } 845 846 static StaticInstPtr 847 decodeNeonTwoRegAndShift(ExtMachInst machInst) 848 { 849 const uint32_t a = bits(machInst, 11, 8); 850 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 851 const bool b = bits(machInst, 6); 852 const bool l = bits(machInst, 7);
|
| 853 const IntRegIndex vd = 854 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 855 (bits(machInst, 22) << 4))); 856 const IntRegIndex vm = 857 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 858 (bits(machInst, 5) << 4))); 859 unsigned imm6 = bits(machInst, 21, 16); 860 unsigned imm = ((l ? 1 : 0) << 6) | imm6; 861 unsigned size = 3; 862 unsigned lShiftAmt = 0; 863 unsigned bitSel; 864 for (bitSel = 1 << 6; true; bitSel >>= 1) { 865 if (bitSel & imm) 866 break; 867 else if (!size) 868 return new Unknown(machInst); 869 size--; 870 } 871 lShiftAmt = imm6 & ~bitSel; 872 unsigned rShiftAmt = 0; 873 if (a != 0xe && a != 0xf) { 874 if (size > 2) 875 rShiftAmt = 64 - imm6; 876 else 877 rShiftAmt = 2 * (8 << size) - imm6; 878 }
|
484 485 switch (a) { 486 case 0x0:
| 879 880 switch (a) { 881 case 0x0:
|
487 return new WarnUnimplemented("vshr", machInst);
| 882 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 883 b, u, size, machInst, vd, vm, rShiftAmt);
|
488 case 0x1:
| 884 case 0x1:
|
489 return new WarnUnimplemented("vsra", machInst);
| 885 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 886 b, u, size, machInst, vd, vm, rShiftAmt);
|
490 case 0x2:
| 887 case 0x2:
|
491 return new WarnUnimplemented("vrshr", machInst);
| 888 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 889 b, u, size, machInst, vd, vm, rShiftAmt);
|
492 case 0x3:
| 890 case 0x3:
|
493 return new WarnUnimplemented("vrsra", machInst);
| 891 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 892 b, u, size, machInst, vd, vm, rShiftAmt);
|
494 case 0x4: 495 if (u) {
| 893 case 0x4: 894 if (u) {
|
496 return new WarnUnimplemented("vsri", machInst);
| 895 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 896 b, size, machInst, vd, vm, rShiftAmt);
|
497 } else { 498 return new Unknown(machInst); 499 } 500 case 0x5: 501 if (u) {
| 897 } else { 898 return new Unknown(machInst); 899 } 900 case 0x5: 901 if (u) {
|
502 return new WarnUnimplemented("vsli", machInst);
| 902 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 903 b, size, machInst, vd, vm, lShiftAmt);
|
503 } else {
| 904 } else {
|
504 return new WarnUnimplemented("vshl (imm)", machInst);
| 905 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 906 b, size, machInst, vd, vm, lShiftAmt);
|
505 } 506 case 0x6: 507 case 0x7:
| 907 } 908 case 0x6: 909 case 0x7:
|
508 return new WarnUnimplemented("vqshl, vqshlu (imm)", machInst);
| 910 if (u) { 911 if (a == 0x6) { 912 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 913 b, size, machInst, vd, vm, lShiftAmt); 914 } else { 915 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 916 b, size, machInst, vd, vm, lShiftAmt); 917 } 918 } else { 919 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 920 b, size, machInst, vd, vm, lShiftAmt); 921 }
|
509 case 0x8: 510 if (l) { 511 return new Unknown(machInst); 512 } else if (u) {
| 922 case 0x8: 923 if (l) { 924 return new Unknown(machInst); 925 } else if (u) {
|
513 if (b) { 514 return new WarnUnimplemented("vqrshrn, vqrshrun", machInst); 515 } else { 516 return new WarnUnimplemented("vqshrn, vqshrun", machInst); 517 }
| 926 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 927 b, size, machInst, vd, vm, rShiftAmt);
|
518 } else {
| 928 } else {
|
519 if (b) { 520 return new WarnUnimplemented("vrshrn", machInst); 521 } else { 522 return new WarnUnimplemented("vshrn", machInst); 523 }
| 929 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 930 b, size, machInst, vd, vm, rShiftAmt);
|
524 } 525 case 0x9: 526 if (l) { 527 return new Unknown(machInst);
| 931 } 932 case 0x9: 933 if (l) { 934 return new Unknown(machInst);
|
528 } else if (b) { 529 return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
| 935 } else if (u) { 936 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 937 b, size, machInst, vd, vm, rShiftAmt);
|
530 } else {
| 938 } else {
|
531 return new WarnUnimplemented("vqshrn, vqshrun", machInst);
| 939 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 940 b, size, machInst, vd, vm, rShiftAmt);
|
532 } 533 case 0xa: 534 if (l || b) { 535 return new Unknown(machInst); 536 } else {
| 941 } 942 case 0xa: 943 if (l || b) { 944 return new Unknown(machInst); 945 } else {
|
537 // If the shift amount is zero, it's vmovl. 538 return new WarnUnimplemented("vshll, vmovl", machInst);
| 946 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 947 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
|
539 } 540 case 0xe:
| 948 } 949 case 0xe:
|
| 950 if (l) { 951 return new Unknown(machInst); 952 } else { 953 if (bits(imm6, 5) == 0) 954 return new Unknown(machInst); 955 if (u) { 956 if (b) { 957 return new NVcvtu2fpQ<float>( 958 machInst, vd, vm, 64 - imm6); 959 } else { 960 return new NVcvtu2fpD<float>( 961 machInst, vd, vm, 64 - imm6); 962 } 963 } else { 964 if (b) { 965 return new NVcvts2fpQ<float>( 966 machInst, vd, vm, 64 - imm6); 967 } else { 968 return new NVcvts2fpD<float>( 969 machInst, vd, vm, 64 - imm6); 970 } 971 } 972 }
|
541 case 0xf: 542 if (l) { 543 return new Unknown(machInst);
| 973 case 0xf: 974 if (l) { 975 return new Unknown(machInst);
|
544 } else if (a == 0xe) { 545 return new WarnUnimplemented("vcvt (fixed to fp)", machInst); 546 } else if (a == 0xf) { 547 return new WarnUnimplemented("vcvt (fp to fixed)", machInst);
| 976 } else { 977 if (bits(imm6, 5) == 0) 978 return new Unknown(machInst); 979 if (u) { 980 if (b) { 981 return new NVcvt2ufxQ<float>( 982 machInst, vd, vm, 64 - imm6); 983 } else { 984 return new NVcvt2ufxD<float>( 985 machInst, vd, vm, 64 - imm6); 986 } 987 } else { 988 if (b) { 989 return new NVcvt2sfxQ<float>( 990 machInst, vd, vm, 64 - imm6); 991 } else { 992 return new NVcvt2sfxD<float>( 993 machInst, vd, vm, 64 - imm6); 994 } 995 }
|
548 } 549 } 550 return new Unknown(machInst); 551 } 552 553 static StaticInstPtr 554 decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 555 { 556 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 557 const uint32_t a = bits(machInst, 11, 8);
| 996 } 997 } 998 return new Unknown(machInst); 999 } 1000 1001 static StaticInstPtr 1002 decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 1003 { 1004 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1005 const uint32_t a = bits(machInst, 11, 8);
|
558
| 1006 const IntRegIndex vd = 1007 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1008 (bits(machInst, 22) << 4))); 1009 const IntRegIndex vn = 1010 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1011 (bits(machInst, 7) << 4))); 1012 const IntRegIndex vm = 1013 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1014 (bits(machInst, 5) << 4))); 1015 const unsigned size = bits(machInst, 21, 20);
|
559 switch (a) { 560 case 0x0:
| 1016 switch (a) { 1017 case 0x0:
|
561 return new WarnUnimplemented("vaddl", machInst);
| 1018 return decodeNeonUSThreeUSReg<Vaddl>( 1019 u, size, machInst, vd, vn, vm);
|
562 case 0x1:
| 1020 case 0x1:
|
563 return new WarnUnimplemented("vaddw", machInst);
| 1021 return decodeNeonUSThreeUSReg<Vaddw>( 1022 u, size, machInst, vd, vn, vm);
|
564 case 0x2:
| 1023 case 0x2:
|
565 return new WarnUnimplemented("vsubl", machInst);
| 1024 return decodeNeonUSThreeUSReg<Vsubl>( 1025 u, size, machInst, vd, vn, vm);
|
566 case 0x3:
| 1026 case 0x3:
|
567 return new WarnUnimplemented("vsubw", machInst);
| 1027 return decodeNeonUSThreeUSReg<Vsubw>( 1028 u, size, machInst, vd, vn, vm);
|
568 case 0x4: 569 if (u) {
| 1029 case 0x4: 1030 if (u) {
|
570 return new WarnUnimplemented("vraddhn", machInst);
| 1031 return decodeNeonUThreeUSReg<Vraddhn>( 1032 size, machInst, vd, vn, vm);
|
571 } else {
| 1033 } else {
|
572 return new WarnUnimplemented("vaddhn", machInst);
| 1034 return decodeNeonUThreeUSReg<Vaddhn>( 1035 size, machInst, vd, vn, vm);
|
573 } 574 case 0x5:
| 1036 } 1037 case 0x5:
|
575 return new WarnUnimplemented("vabal", machInst);
| 1038 return decodeNeonUSThreeUSReg<Vabal>( 1039 u, size, machInst, vd, vn, vm);
|
576 case 0x6: 577 if (u) {
| 1040 case 0x6: 1041 if (u) {
|
578 return new WarnUnimplemented("vrsubhn", machInst);
| 1042 return decodeNeonUThreeUSReg<Vrsubhn>( 1043 size, machInst, vd, vn, vm);
|
579 } else {
| 1044 } else {
|
580 return new WarnUnimplemented("vsubhn", machInst);
| 1045 return decodeNeonUThreeUSReg<Vsubhn>( 1046 size, machInst, vd, vn, vm);
|
581 } 582 case 0x7: 583 if (bits(machInst, 23)) {
| 1047 } 1048 case 0x7: 1049 if (bits(machInst, 23)) {
|
584 return new WarnUnimplemented("vabdl (int)", machInst);
| 1050 return decodeNeonUSThreeUSReg<Vabdl>( 1051 u, size, machInst, vd, vn, vm);
|
585 } else {
| 1052 } else {
|
586 return new WarnUnimplemented("vabd (int)", machInst);
| 1053 return decodeNeonUSThreeReg<VabdD, VabdQ>( 1054 bits(machInst, 6), u, size, machInst, vd, vn, vm);
|
587 } 588 case 0x8:
| 1055 } 1056 case 0x8:
|
589 return new WarnUnimplemented("vmlal (int)", machInst);
| 1057 return decodeNeonUSThreeUSReg<Vmlal>( 1058 u, size, machInst, vd, vn, vm);
|
590 case 0xa:
| 1059 case 0xa:
|
591 return new WarnUnimplemented("vmlsl (int)", machInst);
| 1060 return decodeNeonUSThreeUSReg<Vmlsl>( 1061 u, size, machInst, vd, vn, vm);
|
592 case 0x9:
| 1062 case 0x9:
|
593 if (bits(machInst, 23) == 0) { 594 if (bits(machInst, 4) == 0) { 595 if (u) { 596 return new WarnUnimplemented("vmls (int)", machInst); 597 } else { 598 return new WarnUnimplemented("vmla (int)", machInst); 599 } 600 } else { 601 if (u) { 602 return new WarnUnimplemented("vmul (poly)", machInst); 603 } else { 604 return new WarnUnimplemented("vmul (int)", machInst); 605 } 606 }
| 1063 if (u) { 1064 return new Unknown(machInst);
|
607 } else {
| 1065 } else {
|
608 return new WarnUnimplemented("vqdmlal", machInst);
| 1066 return decodeNeonSThreeUSReg<Vqdmlal>( 1067 size, machInst, vd, vn, vm);
|
609 } 610 case 0xb:
| 1068 } 1069 case 0xb:
|
611 if (!u) {
| 1070 if (u) {
|
612 return new Unknown(machInst); 613 } else {
| 1071 return new Unknown(machInst); 1072 } else {
|
614 return new WarnUnimplemented("vqdmlsl", machInst);
| 1073 return decodeNeonSThreeUSReg<Vqdmlsl>( 1074 size, machInst, vd, vn, vm);
|
615 } 616 case 0xc:
| 1075 } 1076 case 0xc:
|
617 return new WarnUnimplemented("vmull (int)", machInst);
| 1077 return decodeNeonUSThreeUSReg<Vmull>( 1078 u, size, machInst, vd, vn, vm);
|
618 case 0xd:
| 1079 case 0xd:
|
619 if (!u) {
| 1080 if (u) {
|
620 return new Unknown(machInst); 621 } else {
| 1081 return new Unknown(machInst); 1082 } else {
|
622 return new WarnUnimplemented("vqdmull", machInst);
| 1083 return decodeNeonSThreeUSReg<Vqdmull>( 1084 size, machInst, vd, vn, vm);
|
623 } 624 case 0xe:
| 1085 } 1086 case 0xe:
|
625 return new WarnUnimplemented("vmull (poly)", machInst);
| 1087 return decodeNeonUThreeUSReg<Vmullp>( 1088 size, machInst, vd, vn, vm);
|
626 } 627 return new Unknown(machInst); 628 } 629 630 static StaticInstPtr 631 decodeNeonTwoRegScalar(ExtMachInst machInst) 632 { 633 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 634 const uint32_t a = bits(machInst, 11, 8);
| 1089 } 1090 return new Unknown(machInst); 1091 } 1092 1093 static StaticInstPtr 1094 decodeNeonTwoRegScalar(ExtMachInst machInst) 1095 { 1096 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1097 const uint32_t a = bits(machInst, 11, 8);
|
635
| 1098 const unsigned size = bits(machInst, 21, 20); 1099 const IntRegIndex vd = 1100 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1101 (bits(machInst, 22) << 4))); 1102 const IntRegIndex vn = 1103 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1104 (bits(machInst, 7) << 4))); 1105 const IntRegIndex vm = (size == 2) ? 1106 (IntRegIndex)(2 * bits(machInst, 3, 0)) : 1107 (IntRegIndex)(2 * bits(machInst, 2, 0)); 1108 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 1109 (bits(machInst, 3) | (bits(machInst, 5) << 1));
|
636 switch (a) { 637 case 0x0:
| 1110 switch (a) { 1111 case 0x0:
|
638 return new WarnUnimplemented("vmla (int scalar)", machInst);
| 1112 if (u) { 1113 switch (size) { 1114 case 1: 1115 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 1116 case 2: 1117 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index); 1118 default: 1119 return new Unknown(machInst); 1120 } 1121 } else { 1122 switch (size) { 1123 case 1: 1124 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index); 1125 case 2: 1126 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 1127 default: 1128 return new Unknown(machInst); 1129 } 1130 }
|
639 case 0x1:
| 1131 case 0x1:
|
640 return new WarnUnimplemented("vmla (fp scalar)", machInst);
| 1132 if (u) 1133 return new VmlasQFp<float>(machInst, vd, vn, vm, index); 1134 else 1135 return new VmlasDFp<float>(machInst, vd, vn, vm, index);
|
641 case 0x4:
| 1136 case 0x4:
|
642 return new WarnUnimplemented("vmls (int scalar)", machInst);
| 1137 if (u) { 1138 switch (size) { 1139 case 1: 1140 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 1141 case 2: 1142 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index); 1143 default: 1144 return new Unknown(machInst); 1145 } 1146 } else { 1147 switch (size) { 1148 case 1: 1149 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index); 1150 case 2: 1151 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 1152 default: 1153 return new Unknown(machInst); 1154 } 1155 }
|
643 case 0x5:
| 1156 case 0x5:
|
644 return new WarnUnimplemented("vmls (fp scalar)", machInst);
| 1157 if (u) 1158 return new VmlssQFp<float>(machInst, vd, vn, vm, index); 1159 else 1160 return new VmlssDFp<float>(machInst, vd, vn, vm, index);
|
645 case 0x2:
| 1161 case 0x2:
|
646 return new WarnUnimplemented("vmlal (scalar)", machInst);
| 1162 if (u) { 1163 switch (size) { 1164 case 1: 1165 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 1166 case 2: 1167 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 1168 default: 1169 return new Unknown(machInst); 1170 } 1171 } else { 1172 switch (size) { 1173 case 1: 1174 return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 1175 case 2: 1176 return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 1177 default: 1178 return new Unknown(machInst); 1179 } 1180 }
|
647 case 0x6:
| 1181 case 0x6:
|
648 return new WarnUnimplemented("vmlsl (scalar)", machInst);
| 1182 if (u) { 1183 switch (size) { 1184 case 1: 1185 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 1186 case 2: 1187 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 1188 default: 1189 return new Unknown(machInst); 1190 } 1191 } else { 1192 switch (size) { 1193 case 1: 1194 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 1195 case 2: 1196 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 1197 default: 1198 return new Unknown(machInst); 1199 } 1200 }
|
649 case 0x3: 650 if (u) { 651 return new Unknown(machInst); 652 } else {
| 1201 case 0x3: 1202 if (u) { 1203 return new Unknown(machInst); 1204 } else {
|
653 return new WarnUnimplemented("vqdmlal", machInst);
| 1205 switch (size) { 1206 case 1: 1207 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 1208 case 2: 1209 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 1210 default: 1211 return new Unknown(machInst); 1212 }
|
654 } 655 case 0x7: 656 if (u) { 657 return new Unknown(machInst); 658 } else {
| 1213 } 1214 case 0x7: 1215 if (u) { 1216 return new Unknown(machInst); 1217 } else {
|
659 return new WarnUnimplemented("vqdmlsl", machInst);
| 1218 switch (size) { 1219 case 1: 1220 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 1221 case 2: 1222 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 1223 default: 1224 return new Unknown(machInst); 1225 }
|
660 } 661 case 0x8:
| 1226 } 1227 case 0x8:
|
662 return new WarnUnimplemented("vmul (int scalar)", machInst);
| 1228 if (u) { 1229 switch (size) { 1230 case 1: 1231 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 1232 case 2: 1233 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index); 1234 default: 1235 return new Unknown(machInst); 1236 } 1237 } else { 1238 switch (size) { 1239 case 1: 1240 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index); 1241 case 2: 1242 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 1243 default: 1244 return new Unknown(machInst); 1245 } 1246 }
|
663 case 0x9:
| 1247 case 0x9:
|
664 return new WarnUnimplemented("vmul (fp scalar)", machInst);
| 1248 if (u) 1249 return new VmulsQFp<float>(machInst, vd, vn, vm, index); 1250 else 1251 return new VmulsDFp<float>(machInst, vd, vn, vm, index);
|
665 case 0xa:
| 1252 case 0xa:
|
666 return new WarnUnimplemented("vmull (scalar)", machInst);
| 1253 if (u) { 1254 switch (size) { 1255 case 1: 1256 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 1257 case 2: 1258 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 1259 default: 1260 return new Unknown(machInst); 1261 } 1262 } else { 1263 switch (size) { 1264 case 1: 1265 return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 1266 case 2: 1267 return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 1268 default: 1269 return new Unknown(machInst); 1270 } 1271 }
|
667 case 0xb: 668 if (u) { 669 return new Unknown(machInst); 670 } else {
| 1272 case 0xb: 1273 if (u) { 1274 return new Unknown(machInst); 1275 } else {
|
671 return new WarnUnimplemented("vqdmull", machInst);
| 1276 if (u) { 1277 switch (size) { 1278 case 1: 1279 return new Vqdmulls<uint16_t>( 1280 machInst, vd, vn, vm, index); 1281 case 2: 1282 return new Vqdmulls<uint32_t>( 1283 machInst, vd, vn, vm, index); 1284 default: 1285 return new Unknown(machInst); 1286 } 1287 } else { 1288 switch (size) { 1289 case 1: 1290 return new Vqdmulls<int16_t>( 1291 machInst, vd, vn, vm, index); 1292 case 2: 1293 return new Vqdmulls<int32_t>( 1294 machInst, vd, vn, vm, index); 1295 default: 1296 return new Unknown(machInst); 1297 } 1298 }
|
672 } 673 case 0xc:
| 1299 } 1300 case 0xc:
|
674 return new WarnUnimplemented("vqdmulh", machInst);
| 1301 if (u) { 1302 switch (size) { 1303 case 1: 1304 return new VqdmulhsQ<int16_t>( 1305 machInst, vd, vn, vm, index); 1306 case 2: 1307 return new VqdmulhsQ<int32_t>( 1308 machInst, vd, vn, vm, index); 1309 default: 1310 return new Unknown(machInst); 1311 } 1312 } else { 1313 switch (size) { 1314 case 1: 1315 return new VqdmulhsD<int16_t>( 1316 machInst, vd, vn, vm, index); 1317 case 2: 1318 return new VqdmulhsD<int32_t>( 1319 machInst, vd, vn, vm, index); 1320 default: 1321 return new Unknown(machInst); 1322 } 1323 }
|
675 case 0xd:
| 1324 case 0xd:
|
676 return new WarnUnimplemented("vqrdmulh", machInst);
| 1325 if (u) { 1326 switch (size) { 1327 case 1: 1328 return new VqrdmulhsQ<int16_t>( 1329 machInst, vd, vn, vm, index); 1330 case 2: 1331 return new VqrdmulhsQ<int32_t>( 1332 machInst, vd, vn, vm, index); 1333 default: 1334 return new Unknown(machInst); 1335 } 1336 } else { 1337 switch (size) { 1338 case 1: 1339 return new VqrdmulhsD<int16_t>( 1340 machInst, vd, vn, vm, index); 1341 case 2: 1342 return new VqrdmulhsD<int32_t>( 1343 machInst, vd, vn, vm, index); 1344 default: 1345 return new Unknown(machInst); 1346 } 1347 }
|
677 } 678 return new Unknown(machInst); 679 } 680 681 static StaticInstPtr 682 decodeNeonTwoRegMisc(ExtMachInst machInst) 683 { 684 const uint32_t a = bits(machInst, 17, 16); 685 const uint32_t b = bits(machInst, 10, 6);
| 1348 } 1349 return new Unknown(machInst); 1350 } 1351 1352 static StaticInstPtr 1353 decodeNeonTwoRegMisc(ExtMachInst machInst) 1354 { 1355 const uint32_t a = bits(machInst, 17, 16); 1356 const uint32_t b = bits(machInst, 10, 6);
|
| 1357 const bool q = bits(machInst, 6); 1358 const IntRegIndex vd = 1359 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1360 (bits(machInst, 22) << 4))); 1361 const IntRegIndex vm = 1362 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1363 (bits(machInst, 5) << 4))); 1364 const unsigned size = bits(machInst, 19, 18);
|
686 switch (a) { 687 case 0x0: 688 switch (bits(b, 4, 1)) { 689 case 0x0:
| 1365 switch (a) { 1366 case 0x0: 1367 switch (bits(b, 4, 1)) { 1368 case 0x0:
|
690 return new WarnUnimplemented("vrev64", machInst);
| 1369 switch (size) { 1370 case 0: 1371 if (q) { 1372 return new NVrev64Q<uint8_t>(machInst, vd, vm); 1373 } else { 1374 return new NVrev64D<uint8_t>(machInst, vd, vm); 1375 } 1376 case 1: 1377 if (q) { 1378 return new NVrev64Q<uint16_t>(machInst, vd, vm); 1379 } else { 1380 return new NVrev64D<uint16_t>(machInst, vd, vm); 1381 } 1382 case 2: 1383 if (q) { 1384 return new NVrev64Q<uint32_t>(machInst, vd, vm); 1385 } else { 1386 return new NVrev64D<uint32_t>(machInst, vd, vm); 1387 } 1388 default: 1389 return new Unknown(machInst); 1390 }
|
691 case 0x1:
| 1391 case 0x1:
|
692 return new WarnUnimplemented("vrev32", machInst);
| 1392 switch (size) { 1393 case 0: 1394 if (q) { 1395 return new NVrev32Q<uint8_t>(machInst, vd, vm); 1396 } else { 1397 return new NVrev32D<uint8_t>(machInst, vd, vm); 1398 } 1399 case 1: 1400 if (q) { 1401 return new NVrev32Q<uint16_t>(machInst, vd, vm); 1402 } else { 1403 return new NVrev32D<uint16_t>(machInst, vd, vm); 1404 } 1405 default: 1406 return new Unknown(machInst); 1407 }
|
693 case 0x2:
| 1408 case 0x2:
|
694 return new WarnUnimplemented("vrev16", machInst);
| 1409 if (size != 0) { 1410 return new Unknown(machInst); 1411 } else if (q) { 1412 return new NVrev16Q<uint8_t>(machInst, vd, vm); 1413 } else { 1414 return new NVrev16D<uint8_t>(machInst, vd, vm); 1415 }
|
695 case 0x4:
| 1416 case 0x4:
|
| 1417 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1418 q, size, machInst, vd, vm);
|
696 case 0x5:
| 1419 case 0x5:
|
697 return new WarnUnimplemented("vpaddl", machInst);
| 1420 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1421 q, size, machInst, vd, vm);
|
698 case 0x8:
| 1422 case 0x8:
|
699 return new WarnUnimplemented("vcls", machInst);
| 1423 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 1424 q, size, machInst, vd, vm);
|
700 case 0x9:
| 1425 case 0x9:
|
701 return new WarnUnimplemented("vclz", machInst);
| 1426 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 1427 q, size, machInst, vd, vm);
|
702 case 0xa:
| 1428 case 0xa:
|
703 return new WarnUnimplemented("vcnt", machInst);
| 1429 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 1430 q, size, machInst, vd, vm);
|
704 case 0xb:
| 1431 case 0xb:
|
705 return new WarnUnimplemented("vmvn (reg)", machInst);
| 1432 if (q) 1433 return new NVmvnQ<uint64_t>(machInst, vd, vm); 1434 else 1435 return new NVmvnD<uint64_t>(machInst, vd, vm);
|
706 case 0xc:
| 1436 case 0xc:
|
| 1437 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 1438 q, size, machInst, vd, vm);
|
707 case 0xd:
| 1439 case 0xd:
|
708 return new WarnUnimplemented("vpadal", machInst);
| 1440 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 1441 q, size, machInst, vd, vm);
|
709 case 0xe:
| 1442 case 0xe:
|
710 return new WarnUnimplemented("vqabs", machInst);
| 1443 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 1444 q, size, machInst, vd, vm);
|
711 case 0xf:
| 1445 case 0xf:
|
712 return new WarnUnimplemented("vqneg", machInst);
| 1446 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 1447 q, size, machInst, vd, vm);
|
713 default: 714 return new Unknown(machInst); 715 } 716 case 0x1: 717 switch (bits(b, 3, 1)) { 718 case 0x0:
| 1448 default: 1449 return new Unknown(machInst); 1450 } 1451 case 0x1: 1452 switch (bits(b, 3, 1)) { 1453 case 0x0:
|
719 return new WarnUnimplemented("vcgt (imm #0)", machInst);
| 1454 if (bits(b, 4)) { 1455 if (q) { 1456 return new NVcgtQFp<float>(machInst, vd, vm); 1457 } else { 1458 return new NVcgtDFp<float>(machInst, vd, vm); 1459 } 1460 } else { 1461 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 1462 q, size, machInst, vd, vm); 1463 }
|
720 case 0x1:
| 1464 case 0x1:
|
721 return new WarnUnimplemented("vcge (imm #0)", machInst);
| 1465 if (bits(b, 4)) { 1466 if (q) { 1467 return new NVcgeQFp<float>(machInst, vd, vm); 1468 } else { 1469 return new NVcgeDFp<float>(machInst, vd, vm); 1470 } 1471 } else { 1472 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 1473 q, size, machInst, vd, vm); 1474 }
|
722 case 0x2:
| 1475 case 0x2:
|
723 return new WarnUnimplemented("vceq (imm #0)", machInst);
| 1476 if (bits(b, 4)) { 1477 if (q) { 1478 return new NVceqQFp<float>(machInst, vd, vm); 1479 } else { 1480 return new NVceqDFp<float>(machInst, vd, vm); 1481 } 1482 } else { 1483 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 1484 q, size, machInst, vd, vm); 1485 }
|
724 case 0x3:
| 1486 case 0x3:
|
725 return new WarnUnimplemented("vcle (imm #0)", machInst);
| 1487 if (bits(b, 4)) { 1488 if (q) { 1489 return new NVcleQFp<float>(machInst, vd, vm); 1490 } else { 1491 return new NVcleDFp<float>(machInst, vd, vm); 1492 } 1493 } else { 1494 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 1495 q, size, machInst, vd, vm); 1496 }
|
726 case 0x4:
| 1497 case 0x4:
|
727 return new WarnUnimplemented("vclt (imm #0)", machInst);
| 1498 if (bits(b, 4)) { 1499 if (q) { 1500 return new NVcltQFp<float>(machInst, vd, vm); 1501 } else { 1502 return new NVcltDFp<float>(machInst, vd, vm); 1503 } 1504 } else { 1505 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 1506 q, size, machInst, vd, vm); 1507 }
|
728 case 0x6:
| 1508 case 0x6:
|
729 return new WarnUnimplemented("vabs (imm #0)", machInst);
| 1509 if (bits(machInst, 10)) { 1510 if (q) 1511 return new NVabsQFp<float>(machInst, vd, vm); 1512 else 1513 return new NVabsDFp<float>(machInst, vd, vm); 1514 } else { 1515 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 1516 q, size, machInst, vd, vm); 1517 }
|
730 case 0x7:
| 1518 case 0x7:
|
731 return new WarnUnimplemented("vneg (imm #0)", machInst);
| 1519 if (bits(machInst, 10)) { 1520 if (q) 1521 return new NVnegQFp<float>(machInst, vd, vm); 1522 else 1523 return new NVnegDFp<float>(machInst, vd, vm); 1524 } else { 1525 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 1526 q, size, machInst, vd, vm); 1527 }
|
732 } 733 case 0x2: 734 switch (bits(b, 4, 1)) { 735 case 0x0:
| 1528 } 1529 case 0x2: 1530 switch (bits(b, 4, 1)) { 1531 case 0x0:
|
736 return new WarnUnimplemented("vswp", machInst);
| 1532 if (q) 1533 return new NVswpQ<uint64_t>(machInst, vd, vm); 1534 else 1535 return new NVswpD<uint64_t>(machInst, vd, vm);
|
737 case 0x1:
| 1536 case 0x1:
|
738 return new WarnUnimplemented("vtrn", machInst);
| 1537 return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>( 1538 q, size, machInst, vd, vm);
|
739 case 0x2:
| 1539 case 0x2:
|
740 return new WarnUnimplemented("vuzp", machInst);
| 1540 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 1541 q, size, machInst, vd, vm);
|
741 case 0x3:
| 1542 case 0x3:
|
742 return new WarnUnimplemented("vzip", machInst);
| 1543 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 1544 q, size, machInst, vd, vm);
|
743 case 0x4: 744 if (b == 0x8) {
| 1545 case 0x4: 1546 if (b == 0x8) {
|
745 return new WarnUnimplemented("vmovn", machInst);
| 1547 return decodeNeonUTwoMiscUSReg<NVmovn>( 1548 size, machInst, vd, vm);
|
746 } else {
| 1549 } else {
|
747 return new WarnUnimplemented("vqmovun", machInst);
| 1550 return decodeNeonSTwoMiscUSReg<NVqmovuns>( 1551 size, machInst, vd, vm);
|
748 } 749 case 0x5:
| 1552 } 1553 case 0x5:
|
750 return new WarnUnimplemented("vqmovn", machInst);
| 1554 if (q) { 1555 return decodeNeonUTwoMiscUSReg<NVqmovun>( 1556 size, machInst, vd, vm); 1557 } else { 1558 return decodeNeonSTwoMiscUSReg<NVqmovn>( 1559 size, machInst, vd, vm); 1560 }
|
751 case 0x6: 752 if (b == 0xc) {
| 1561 case 0x6: 1562 if (b == 0xc) {
|
753 return new WarnUnimplemented("vshll", machInst);
| 1563 const IntRegIndex vd = 1564 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1565 (bits(machInst, 22) << 4))); 1566 const IntRegIndex vm = 1567 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1568 (bits(machInst, 5) << 4))); 1569 unsigned size = bits(machInst, 19, 18); 1570 return decodeNeonSTwoShiftUSReg<NVshll>( 1571 size, machInst, vd, vm, 8 << size);
|
754 } else { 755 return new Unknown(machInst); 756 } 757 case 0xc: 758 case 0xe: 759 if (b == 0x18) {
| 1572 } else { 1573 return new Unknown(machInst); 1574 } 1575 case 0xc: 1576 case 0xe: 1577 if (b == 0x18) {
|
760 return new WarnUnimplemented("vcvt (single to half)", 761 machInst);
| 1578 if (size != 1 || (vm % 2)) 1579 return new Unknown(machInst); 1580 return new NVcvts2h<uint16_t>(machInst, vd, vm);
|
762 } else if (b == 0x1c) {
| 1581 } else if (b == 0x1c) {
|
763 return new WarnUnimplemented("vcvt (half to single)", 764 machInst);
| 1582 if (size != 1 || (vd % 2)) 1583 return new Unknown(machInst); 1584 return new NVcvth2s<uint16_t>(machInst, vd, vm);
|
765 } else { 766 return new Unknown(machInst); 767 } 768 default: 769 return new Unknown(machInst); 770 } 771 case 0x3: 772 if (bits(b, 4, 3) == 0x3) {
| 1585 } else { 1586 return new Unknown(machInst); 1587 } 1588 default: 1589 return new Unknown(machInst); 1590 } 1591 case 0x3: 1592 if (bits(b, 4, 3) == 0x3) {
|
773 return new WarnUnimplemented("vcvt (fp and int)", machInst);
| 1593 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1594 return new Unknown(machInst); 1595 } else { 1596 if (bits(b, 2)) { 1597 if (bits(b, 1)) { 1598 if (q) { 1599 return new NVcvt2ufxQ<float>( 1600 machInst, vd, vm, 0); 1601 } else { 1602 return new NVcvt2ufxD<float>( 1603 machInst, vd, vm, 0); 1604 } 1605 } else { 1606 if (q) { 1607 return new NVcvt2sfxQ<float>( 1608 machInst, vd, vm, 0); 1609 } else { 1610 return new NVcvt2sfxD<float>( 1611 machInst, vd, vm, 0); 1612 } 1613 } 1614 } else { 1615 if (bits(b, 1)) { 1616 if (q) { 1617 return new NVcvtu2fpQ<float>( 1618 machInst, vd, vm, 0); 1619 } else { 1620 return new NVcvtu2fpD<float>( 1621 machInst, vd, vm, 0); 1622 } 1623 } else { 1624 if (q) { 1625 return new NVcvts2fpQ<float>( 1626 machInst, vd, vm, 0); 1627 } else { 1628 return new NVcvts2fpD<float>( 1629 machInst, vd, vm, 0); 1630 } 1631 } 1632 } 1633 }
|
774 } else if ((b & 0x1a) == 0x10) {
| 1634 } else if ((b & 0x1a) == 0x10) {
|
775 return new WarnUnimplemented("vrecpe", machInst);
| 1635 if (bits(b, 2)) { 1636 if (q) { 1637 return new NVrecpeQFp<float>(machInst, vd, vm); 1638 } else { 1639 return new NVrecpeDFp<float>(machInst, vd, vm); 1640 } 1641 } else { 1642 if (q) { 1643 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1644 } else { 1645 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1646 } 1647 }
|
776 } else if ((b & 0x1a) == 0x12) {
| 1648 } else if ((b & 0x1a) == 0x12) {
|
777 return new WarnUnimplemented("vrsqrte", machInst);
| 1649 if (bits(b, 2)) { 1650 if (q) { 1651 return new NVrsqrteQFp<float>(machInst, vd, vm); 1652 } else { 1653 return new NVrsqrteDFp<float>(machInst, vd, vm); 1654 } 1655 } else { 1656 if (q) { 1657 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1658 } else { 1659 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1660 } 1661 }
|
778 } else { 779 return new Unknown(machInst); 780 } 781 } 782 return new Unknown(machInst); 783 } 784 785 StaticInstPtr 786 decodeNeonData(ExtMachInst machInst) 787 { 788 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 789 const uint32_t a = bits(machInst, 23, 19); 790 const uint32_t b = bits(machInst, 11, 8); 791 const uint32_t c = bits(machInst, 7, 4); 792 if (bits(a, 4) == 0) { 793 return decodeNeonThreeRegistersSameLength(machInst); 794 } else if ((c & 0x9) == 1) { 795 if ((a & 0x7) == 0) { 796 return decodeNeonOneRegModImm(machInst); 797 } else { 798 return decodeNeonTwoRegAndShift(machInst); 799 } 800 } else if ((c & 0x9) == 9) { 801 return decodeNeonTwoRegAndShift(machInst);
| 1662 } else { 1663 return new Unknown(machInst); 1664 } 1665 } 1666 return new Unknown(machInst); 1667 } 1668 1669 StaticInstPtr 1670 decodeNeonData(ExtMachInst machInst) 1671 { 1672 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1673 const uint32_t a = bits(machInst, 23, 19); 1674 const uint32_t b = bits(machInst, 11, 8); 1675 const uint32_t c = bits(machInst, 7, 4); 1676 if (bits(a, 4) == 0) { 1677 return decodeNeonThreeRegistersSameLength(machInst); 1678 } else if ((c & 0x9) == 1) { 1679 if ((a & 0x7) == 0) { 1680 return decodeNeonOneRegModImm(machInst); 1681 } else { 1682 return decodeNeonTwoRegAndShift(machInst); 1683 } 1684 } else if ((c & 0x9) == 9) { 1685 return decodeNeonTwoRegAndShift(machInst);
|
802 } else if ((c & 0x5) == 0) { 803 if (bits(a, 3, 2) != 0x3) {
| 1686 } else if (bits(a, 2, 1) != 0x3) { 1687 if ((c & 0x5) == 0) {
|
804 return decodeNeonThreeRegDiffLengths(machInst);
| 1688 return decodeNeonThreeRegDiffLengths(machInst);
|
805 } 806 } else if ((c & 0x5) == 4) { 807 if (bits(a, 3, 2) != 0x3) {
| 1689 } else if ((c & 0x5) == 4) {
|
808 return decodeNeonTwoRegScalar(machInst); 809 } 810 } else if ((a & 0x16) == 0x16) {
| 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)));
|
811 if (!u) { 812 if (bits(c, 0) == 0) {
| 1702 if (!u) { 1703 if (bits(c, 0) == 0) {
|
813 return new WarnUnimplemented("vext", machInst);
| 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 }
|
814 } 815 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 816 return decodeNeonTwoRegMisc(machInst); 817 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
| 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);
|
818 if (bits(machInst, 6) == 0) {
| 1720 if (bits(machInst, 6) == 0) {
|
819 return new WarnUnimplemented("vtbl", machInst);
| 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 }
|
820 } else {
| 1731 } else {
|
821 return new WarnUnimplemented("vtbx", machInst);
| 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 }
|
822 } 823 } else if (b == 0xc && (c & 0x9) == 0) {
| 1742 } 1743 } else if (b == 0xc && (c & 0x9) == 0) {
|
824 return new WarnUnimplemented("vdup (scalar)", machInst);
| 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);
|
825 } 826 } 827 return new Unknown(machInst); 828 } 829 ''' 830}}; 831 832def format ThumbNeonMem() {{ 833 decode_block = ''' 834 return decodeNeonMem(machInst); 835 ''' 836}}; 837 838def format ThumbNeonData() {{ 839 decode_block = '''
| 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 = '''
|
840 return decodeNeonMem(machInst);
| 1771 return decodeNeonData(machInst);
|
841 ''' 842}}; 843 844let {{ 845 header_output = ''' 846 StaticInstPtr 847 decodeExtensionRegLoadStore(ExtMachInst machInst); 848 ''' 849 decoder_output = ''' 850 StaticInstPtr 851 decodeExtensionRegLoadStore(ExtMachInst machInst) 852 { 853 const uint32_t opcode = bits(machInst, 24, 20); 854 const uint32_t offset = bits(machInst, 7, 0); 855 const bool single = (bits(machInst, 8) == 0); 856 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 857 RegIndex vd; 858 if (single) { 859 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 860 bits(machInst, 22)); 861 } else { 862 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 863 (bits(machInst, 22) << 5)); 864 } 865 switch (bits(opcode, 4, 3)) { 866 case 0x0: 867 if (bits(opcode, 4, 1) == 0x2 && 868 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 869 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 870 if ((bits(machInst, 7, 4) & 0xd) != 1) { 871 break; 872 } 873 const IntRegIndex rt = 874 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 875 const IntRegIndex rt2 = 876 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 877 const bool op = bits(machInst, 20); 878 uint32_t vm; 879 if (single) { 880 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 881 } else { 882 vm = (bits(machInst, 3, 0) << 1) | 883 (bits(machInst, 5) << 5); 884 } 885 if (op) { 886 return new Vmov2Core2Reg(machInst, rt, rt2, 887 (IntRegIndex)vm); 888 } else { 889 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 890 rt, rt2); 891 } 892 } 893 break; 894 case 0x1: 895 {
| 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 {
|
896 if (offset == 0 || vd + offset > NumFloatArchRegs) {
| 1827 if (offset == 0 || vd + offset/2 > NumFloatArchRegs) {
|
897 break; 898 } 899 switch (bits(opcode, 1, 0)) { 900 case 0x0: 901 return new VLdmStm(machInst, rn, vd, single, 902 true, false, false, offset); 903 case 0x1: 904 return new VLdmStm(machInst, rn, vd, single, 905 true, false, true, offset); 906 case 0x2: 907 return new VLdmStm(machInst, rn, vd, single, 908 true, true, false, offset); 909 case 0x3: 910 // If rn == sp, then this is called vpop. 911 return new VLdmStm(machInst, rn, vd, single, 912 true, true, true, offset); 913 } 914 } 915 case 0x2: 916 if (bits(opcode, 1, 0) == 0x2) { 917 // If rn == sp, then this is called vpush. 918 return new VLdmStm(machInst, rn, vd, single, 919 false, true, false, offset); 920 } else if (bits(opcode, 1, 0) == 0x3) { 921 return new VLdmStm(machInst, rn, vd, single, 922 false, true, true, offset); 923 } 924 // Fall through on purpose 925 case 0x3: 926 const bool up = (bits(machInst, 23) == 1); 927 const uint32_t imm = bits(machInst, 7, 0) << 2; 928 RegIndex vd; 929 if (single) { 930 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 931 (bits(machInst, 22))); 932 } else { 933 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 934 (bits(machInst, 22) << 5)); 935 } 936 if (bits(opcode, 1, 0) == 0x0) { 937 if (single) { 938 if (up) { 939 return new %(vstr_us)s(machInst, vd, rn, up, imm); 940 } else { 941 return new %(vstr_s)s(machInst, vd, rn, up, imm); 942 } 943 } else { 944 if (up) { 945 return new %(vstr_ud)s(machInst, vd, vd + 1, 946 rn, up, imm); 947 } else { 948 return new %(vstr_d)s(machInst, vd, vd + 1, 949 rn, up, imm); 950 } 951 } 952 } else if (bits(opcode, 1, 0) == 0x1) { 953 if (single) { 954 if (up) { 955 return new %(vldr_us)s(machInst, vd, rn, up, imm); 956 } else { 957 return new %(vldr_s)s(machInst, vd, rn, up, imm); 958 } 959 } else { 960 if (up) { 961 return new %(vldr_ud)s(machInst, vd, vd + 1, 962 rn, up, imm); 963 } else { 964 return new %(vldr_d)s(machInst, vd, vd + 1, 965 rn, up, imm); 966 } 967 } 968 } 969 } 970 return new Unknown(machInst); 971 } 972 ''' % { 973 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 974 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 975 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 976 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 977 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 978 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 979 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 980 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 981 } 982}}; 983 984def format ExtensionRegLoadStore() {{ 985 decode_block = ''' 986 return decodeExtensionRegLoadStore(machInst); 987 ''' 988}}; 989 990let {{ 991 header_output = ''' 992 StaticInstPtr 993 decodeShortFpTransfer(ExtMachInst machInst); 994 ''' 995 decoder_output = ''' 996 StaticInstPtr 997 decodeShortFpTransfer(ExtMachInst machInst) 998 { 999 const uint32_t l = bits(machInst, 20); 1000 const uint32_t c = bits(machInst, 8); 1001 const uint32_t a = bits(machInst, 23, 21); 1002 const uint32_t b = bits(machInst, 6, 5); 1003 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 1004 (machInst.thumb == 0 && machInst.condCode == 0xf)) { 1005 return new Unknown(machInst); 1006 } 1007 if (l == 0 && c == 0) { 1008 if (a == 0) { 1009 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 1010 bits(machInst, 7); 1011 const IntRegIndex rt = 1012 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1013 if (bits(machInst, 20) == 1) { 1014 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 1015 } else { 1016 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 1017 } 1018 } else if (a == 0x7) { 1019 const IntRegIndex rt = 1020 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1021 uint32_t specReg = bits(machInst, 19, 16); 1022 switch (specReg) { 1023 case 0: 1024 specReg = MISCREG_FPSID; 1025 break; 1026 case 1: 1027 specReg = MISCREG_FPSCR; 1028 break; 1029 case 6: 1030 specReg = MISCREG_MVFR1; 1031 break; 1032 case 7: 1033 specReg = MISCREG_MVFR0; 1034 break; 1035 case 8: 1036 specReg = MISCREG_FPEXC; 1037 break; 1038 default: 1039 return new Unknown(machInst); 1040 } 1041 return new Vmsr(machInst, (IntRegIndex)specReg, rt); 1042 } 1043 } else if (l == 0 && c == 1) { 1044 if (bits(a, 2) == 0) { 1045 uint32_t vd = (bits(machInst, 7) << 5) | 1046 (bits(machInst, 19, 16) << 1);
| 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 return new Vmsr(machInst, (IntRegIndex)specReg, rt); 1973 } 1974 } else if (l == 0 && c == 1) { 1975 if (bits(a, 2) == 0) { 1976 uint32_t vd = (bits(machInst, 7) << 5) | 1977 (bits(machInst, 19, 16) << 1);
|
1047 uint32_t index, size;
| 1978 // Handle accessing each single precision half of the vector. 1979 vd += bits(machInst, 21);
|
1048 const IntRegIndex rt = 1049 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1050 if (bits(machInst, 22) == 1) {
| 1980 const IntRegIndex rt = 1981 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1982 if (bits(machInst, 22) == 1) {
|
1051 size = 8; 1052 index = (bits(machInst, 21) << 2) | 1053 bits(machInst, 6, 5);
| 1983 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 1984 rt, bits(machInst, 6, 5));
|
1054 } else if (bits(machInst, 5) == 1) {
| 1985 } else if (bits(machInst, 5) == 1) {
|
1055 size = 16; 1056 index = (bits(machInst, 21) << 1) | 1057 bits(machInst, 6);
| 1986 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 1987 rt, bits(machInst, 6));
|
1058 } else if (bits(machInst, 6) == 0) {
| 1988 } else if (bits(machInst, 6) == 0) {
|
1059 size = 32; 1060 index = bits(machInst, 21);
| 1989 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
|
1061 } else { 1062 return new Unknown(machInst); 1063 }
| 1990 } else { 1991 return new Unknown(machInst); 1992 }
|
1064 if (index >= (32 / size)) { 1065 index -= (32 / size); 1066 vd++; 1067 } 1068 switch (size) { 1069 case 8: 1070 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 1071 rt, index); 1072 case 16: 1073 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 1074 rt, index); 1075 case 32: 1076 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 1077 }
| |
1078 } else if (bits(b, 1) == 0) {
| 1993 } else if (bits(b, 1) == 0) {
|
1079 // A8-594 1080 return new WarnUnimplemented("vdup", machInst);
| 1994 bool q = bits(machInst, 21); 1995 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 1996 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 1997 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 1998 IntRegIndex rt = (IntRegIndex)(uint32_t) 1999 bits(machInst, 15, 12); 2000 if (q) { 2001 switch (be) { 2002 case 0: 2003 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2004 case 1: 2005 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2006 case 2: 2007 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2008 case 3: 2009 return new Unknown(machInst); 2010 } 2011 } else { 2012 switch (be) { 2013 case 0: 2014 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2015 case 1: 2016 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2017 case 2: 2018 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2019 case 3: 2020 return new Unknown(machInst); 2021 } 2022 }
|
1081 } 1082 } else if (l == 1 && c == 0) { 1083 if (a == 0) { 1084 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 1085 bits(machInst, 7); 1086 const IntRegIndex rt = 1087 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1088 if (bits(machInst, 20) == 1) { 1089 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 1090 } else { 1091 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 1092 } 1093 } else if (a == 7) { 1094 const IntRegIndex rt = 1095 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1096 uint32_t specReg = bits(machInst, 19, 16); 1097 switch (specReg) { 1098 case 0: 1099 specReg = MISCREG_FPSID; 1100 break; 1101 case 1: 1102 specReg = MISCREG_FPSCR; 1103 break; 1104 case 6: 1105 specReg = MISCREG_MVFR1; 1106 break; 1107 case 7: 1108 specReg = MISCREG_MVFR0; 1109 break; 1110 case 8: 1111 specReg = MISCREG_FPEXC; 1112 break; 1113 default: 1114 return new Unknown(machInst); 1115 } 1116 if (rt == 0xf) { 1117 CPSR cpsrMask = 0; 1118 cpsrMask.n = 1; 1119 cpsrMask.z = 1; 1120 cpsrMask.c = 1; 1121 cpsrMask.v = 1; 1122 return new VmrsApsr(machInst, INTREG_CONDCODES, 1123 (IntRegIndex)specReg, (uint32_t)cpsrMask); 1124 } else { 1125 return new Vmrs(machInst, rt, (IntRegIndex)specReg); 1126 } 1127 } 1128 } else { 1129 uint32_t vd = (bits(machInst, 7) << 5) | 1130 (bits(machInst, 19, 16) << 1);
| 2023 } 2024 } else if (l == 1 && c == 0) { 2025 if (a == 0) { 2026 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2027 bits(machInst, 7); 2028 const IntRegIndex rt = 2029 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2030 if (bits(machInst, 20) == 1) { 2031 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2032 } else { 2033 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2034 } 2035 } else if (a == 7) { 2036 const IntRegIndex rt = 2037 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2038 uint32_t specReg = bits(machInst, 19, 16); 2039 switch (specReg) { 2040 case 0: 2041 specReg = MISCREG_FPSID; 2042 break; 2043 case 1: 2044 specReg = MISCREG_FPSCR; 2045 break; 2046 case 6: 2047 specReg = MISCREG_MVFR1; 2048 break; 2049 case 7: 2050 specReg = MISCREG_MVFR0; 2051 break; 2052 case 8: 2053 specReg = MISCREG_FPEXC; 2054 break; 2055 default: 2056 return new Unknown(machInst); 2057 } 2058 if (rt == 0xf) { 2059 CPSR cpsrMask = 0; 2060 cpsrMask.n = 1; 2061 cpsrMask.z = 1; 2062 cpsrMask.c = 1; 2063 cpsrMask.v = 1; 2064 return new VmrsApsr(machInst, INTREG_CONDCODES, 2065 (IntRegIndex)specReg, (uint32_t)cpsrMask); 2066 } else { 2067 return new Vmrs(machInst, rt, (IntRegIndex)specReg); 2068 } 2069 } 2070 } else { 2071 uint32_t vd = (bits(machInst, 7) << 5) | 2072 (bits(machInst, 19, 16) << 1);
|
1131 uint32_t index, size;
| 2073 // Handle indexing into each single precision half of the vector. 2074 vd += bits(machInst, 21); 2075 uint32_t index;
|
1132 const IntRegIndex rt = 1133 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1134 const bool u = (bits(machInst, 23) == 1); 1135 if (bits(machInst, 22) == 1) {
| 2076 const IntRegIndex rt = 2077 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2078 const bool u = (bits(machInst, 23) == 1); 2079 if (bits(machInst, 22) == 1) {
|
1136 size = 8; 1137 index = (bits(machInst, 21) << 2) | 1138 bits(machInst, 6, 5); 1139 } else if (bits(machInst, 5) == 1) { 1140 size = 16; 1141 index = (bits(machInst, 21) << 1) | 1142 bits(machInst, 6); 1143 } else if (bits(machInst, 6) == 0 && !u) { 1144 size = 32; 1145 index = bits(machInst, 21); 1146 } else { 1147 return new Unknown(machInst); 1148 } 1149 if (index >= (32 / size)) { 1150 index -= (32 / size); 1151 vd++; 1152 } 1153 switch (size) { 1154 case 8:
| 2080 index = bits(machInst, 6, 5);
|
1155 if (u) { 1156 return new VmovRegCoreUB(machInst, rt, 1157 (IntRegIndex)vd, index); 1158 } else { 1159 return new VmovRegCoreSB(machInst, rt, 1160 (IntRegIndex)vd, index); 1161 }
| 2081 if (u) { 2082 return new VmovRegCoreUB(machInst, rt, 2083 (IntRegIndex)vd, index); 2084 } else { 2085 return new VmovRegCoreSB(machInst, rt, 2086 (IntRegIndex)vd, index); 2087 }
|
1162 case 16:
| 2088 } else if (bits(machInst, 5) == 1) { 2089 index = bits(machInst, 6);
|
1163 if (u) { 1164 return new VmovRegCoreUH(machInst, rt, 1165 (IntRegIndex)vd, index); 1166 } else { 1167 return new VmovRegCoreSH(machInst, rt, 1168 (IntRegIndex)vd, index); 1169 }
| 2090 if (u) { 2091 return new VmovRegCoreUH(machInst, rt, 2092 (IntRegIndex)vd, index); 2093 } else { 2094 return new VmovRegCoreSH(machInst, rt, 2095 (IntRegIndex)vd, index); 2096 }
|
1170 case 32:
| 2097 } else if (bits(machInst, 6) == 0 && !u) {
|
1171 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
| 2098 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
|
| 2099 } else { 2100 return new Unknown(machInst);
|
1172 } 1173 } 1174 return new Unknown(machInst); 1175 } 1176 ''' 1177}}; 1178 1179def format ShortFpTransfer() {{ 1180 decode_block = ''' 1181 return decodeShortFpTransfer(machInst); 1182 ''' 1183}}; 1184 1185let {{ 1186 header_output = ''' 1187 StaticInstPtr 1188 decodeVfpData(ExtMachInst machInst); 1189 ''' 1190 decoder_output = ''' 1191 StaticInstPtr 1192 decodeVfpData(ExtMachInst machInst) 1193 { 1194 const uint32_t opc1 = bits(machInst, 23, 20); 1195 const uint32_t opc2 = bits(machInst, 19, 16); 1196 const uint32_t opc3 = bits(machInst, 7, 6); 1197 //const uint32_t opc4 = bits(machInst, 3, 0); 1198 const bool single = (bits(machInst, 8) == 0); 1199 // Used to select between vcmp and vcmpe. 1200 const bool e = (bits(machInst, 7) == 1); 1201 IntRegIndex vd; 1202 IntRegIndex vm; 1203 IntRegIndex vn; 1204 if (single) { 1205 vd = (IntRegIndex)(bits(machInst, 22) | 1206 (bits(machInst, 15, 12) << 1)); 1207 vm = (IntRegIndex)(bits(machInst, 5) | 1208 (bits(machInst, 3, 0) << 1)); 1209 vn = (IntRegIndex)(bits(machInst, 7) | 1210 (bits(machInst, 19, 16) << 1)); 1211 } else { 1212 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 1213 (bits(machInst, 15, 12) << 1)); 1214 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 1215 (bits(machInst, 3, 0) << 1)); 1216 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 1217 (bits(machInst, 19, 16) << 1)); 1218 } 1219 switch (opc1 & 0xb /* 1011 */) { 1220 case 0x0: 1221 if (bits(machInst, 6) == 0) { 1222 if (single) { 1223 return decodeVfpRegRegRegOp<VmlaS>( 1224 machInst, vd, vn, vm, false); 1225 } else { 1226 return decodeVfpRegRegRegOp<VmlaD>( 1227 machInst, vd, vn, vm, true); 1228 } 1229 } else { 1230 if (single) { 1231 return decodeVfpRegRegRegOp<VmlsS>( 1232 machInst, vd, vn, vm, false); 1233 } else { 1234 return decodeVfpRegRegRegOp<VmlsD>( 1235 machInst, vd, vn, vm, true); 1236 } 1237 } 1238 case 0x1: 1239 if (bits(machInst, 6) == 1) { 1240 if (single) { 1241 return decodeVfpRegRegRegOp<VnmlaS>( 1242 machInst, vd, vn, vm, false); 1243 } else { 1244 return decodeVfpRegRegRegOp<VnmlaD>( 1245 machInst, vd, vn, vm, true); 1246 } 1247 } else { 1248 if (single) { 1249 return decodeVfpRegRegRegOp<VnmlsS>( 1250 machInst, vd, vn, vm, false); 1251 } else { 1252 return decodeVfpRegRegRegOp<VnmlsD>( 1253 machInst, vd, vn, vm, true); 1254 } 1255 } 1256 case 0x2: 1257 if ((opc3 & 0x1) == 0) { 1258 if (single) { 1259 return decodeVfpRegRegRegOp<VmulS>( 1260 machInst, vd, vn, vm, false); 1261 } else { 1262 return decodeVfpRegRegRegOp<VmulD>( 1263 machInst, vd, vn, vm, true); 1264 } 1265 } else { 1266 if (single) { 1267 return decodeVfpRegRegRegOp<VnmulS>( 1268 machInst, vd, vn, vm, false); 1269 } else { 1270 return decodeVfpRegRegRegOp<VnmulD>( 1271 machInst, vd, vn, vm, true); 1272 } 1273 } 1274 case 0x3: 1275 if ((opc3 & 0x1) == 0) { 1276 if (single) { 1277 return decodeVfpRegRegRegOp<VaddS>( 1278 machInst, vd, vn, vm, false); 1279 } else { 1280 return decodeVfpRegRegRegOp<VaddD>( 1281 machInst, vd, vn, vm, true); 1282 } 1283 } else { 1284 if (single) { 1285 return decodeVfpRegRegRegOp<VsubS>( 1286 machInst, vd, vn, vm, false); 1287 } else { 1288 return decodeVfpRegRegRegOp<VsubD>( 1289 machInst, vd, vn, vm, true); 1290 } 1291 } 1292 case 0x8: 1293 if ((opc3 & 0x1) == 0) { 1294 if (single) { 1295 return decodeVfpRegRegRegOp<VdivS>( 1296 machInst, vd, vn, vm, false); 1297 } else { 1298 return decodeVfpRegRegRegOp<VdivD>( 1299 machInst, vd, vn, vm, true); 1300 } 1301 } 1302 break; 1303 case 0xb: 1304 if ((opc3 & 0x1) == 0) { 1305 const uint32_t baseImm = 1306 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 1307 if (single) { 1308 uint32_t imm = vfp_modified_imm(baseImm, false); 1309 return decodeVfpRegImmOp<VmovImmS>( 1310 machInst, vd, imm, false); 1311 } else { 1312 uint64_t imm = vfp_modified_imm(baseImm, true); 1313 return decodeVfpRegImmOp<VmovImmD>( 1314 machInst, vd, imm, true); 1315 } 1316 } 1317 switch (opc2) { 1318 case 0x0: 1319 if (opc3 == 1) { 1320 if (single) { 1321 return decodeVfpRegRegOp<VmovRegS>( 1322 machInst, vd, vm, false); 1323 } else { 1324 return decodeVfpRegRegOp<VmovRegD>( 1325 machInst, vd, vm, true); 1326 } 1327 } else { 1328 if (single) { 1329 return decodeVfpRegRegOp<VabsS>( 1330 machInst, vd, vm, false); 1331 } else { 1332 return decodeVfpRegRegOp<VabsD>( 1333 machInst, vd, vm, true); 1334 } 1335 } 1336 case 0x1: 1337 if (opc3 == 1) { 1338 if (single) { 1339 return decodeVfpRegRegOp<VnegS>( 1340 machInst, vd, vm, false); 1341 } else { 1342 return decodeVfpRegRegOp<VnegD>( 1343 machInst, vd, vm, true); 1344 } 1345 } else { 1346 if (single) { 1347 return decodeVfpRegRegOp<VsqrtS>( 1348 machInst, vd, vm, false); 1349 } else { 1350 return decodeVfpRegRegOp<VsqrtD>( 1351 machInst, vd, vm, true); 1352 } 1353 } 1354 case 0x2: 1355 case 0x3: 1356 { 1357 const bool toHalf = bits(machInst, 16); 1358 const bool top = bits(machInst, 7); 1359 if (top) { 1360 if (toHalf) { 1361 return new VcvtFpSFpHT(machInst, vd, vm); 1362 } else { 1363 return new VcvtFpHTFpS(machInst, vd, vm); 1364 } 1365 } else { 1366 if (toHalf) { 1367 return new VcvtFpSFpHB(machInst, vd, vm); 1368 } else { 1369 return new VcvtFpHBFpS(machInst, vd, vm); 1370 } 1371 } 1372 } 1373 case 0x4: 1374 if (single) { 1375 if (e) { 1376 return new VcmpeS(machInst, vd, vm); 1377 } else { 1378 return new VcmpS(machInst, vd, vm); 1379 } 1380 } else { 1381 if (e) { 1382 return new VcmpeD(machInst, vd, vm); 1383 } else { 1384 return new VcmpD(machInst, vd, vm); 1385 } 1386 } 1387 case 0x5: 1388 if (single) { 1389 if (e) { 1390 return new VcmpeZeroS(machInst, vd, 0); 1391 } else { 1392 return new VcmpZeroS(machInst, vd, 0); 1393 } 1394 } else { 1395 if (e) { 1396 return new VcmpeZeroD(machInst, vd, 0); 1397 } else { 1398 return new VcmpZeroD(machInst, vd, 0); 1399 } 1400 } 1401 case 0x7: 1402 if (opc3 == 0x3) { 1403 if (single) { 1404 vm = (IntRegIndex)(bits(machInst, 5) | 1405 (bits(machInst, 3, 0) << 1)); 1406 return new VcvtFpSFpD(machInst, vd, vm); 1407 } else { 1408 vd = (IntRegIndex)(bits(machInst, 22) | 1409 (bits(machInst, 15, 12) << 1)); 1410 return new VcvtFpDFpS(machInst, vd, vm); 1411 } 1412 } 1413 break; 1414 case 0x8: 1415 if (bits(machInst, 7) == 0) { 1416 if (single) { 1417 return new VcvtUIntFpS(machInst, vd, vm); 1418 } else { 1419 vm = (IntRegIndex)(bits(machInst, 5) | 1420 (bits(machInst, 3, 0) << 1)); 1421 return new VcvtUIntFpD(machInst, vd, vm); 1422 } 1423 } else { 1424 if (single) { 1425 return new VcvtSIntFpS(machInst, vd, vm); 1426 } else { 1427 vm = (IntRegIndex)(bits(machInst, 5) | 1428 (bits(machInst, 3, 0) << 1)); 1429 return new VcvtSIntFpD(machInst, vd, vm); 1430 } 1431 } 1432 case 0xa: 1433 { 1434 const bool half = (bits(machInst, 7) == 0); 1435 const uint32_t imm = bits(machInst, 5) | 1436 (bits(machInst, 3, 0) << 1); 1437 const uint32_t size = 1438 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 1439 if (single) { 1440 if (half) { 1441 return new VcvtSHFixedFpS(machInst, vd, vd, size); 1442 } else { 1443 return new VcvtSFixedFpS(machInst, vd, vd, size); 1444 } 1445 } else { 1446 if (half) { 1447 return new VcvtSHFixedFpD(machInst, vd, vd, size); 1448 } else { 1449 return new VcvtSFixedFpD(machInst, vd, vd, size); 1450 } 1451 } 1452 } 1453 case 0xb: 1454 { 1455 const bool half = (bits(machInst, 7) == 0); 1456 const uint32_t imm = bits(machInst, 5) | 1457 (bits(machInst, 3, 0) << 1); 1458 const uint32_t size = 1459 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 1460 if (single) { 1461 if (half) { 1462 return new VcvtUHFixedFpS(machInst, vd, vd, size); 1463 } else { 1464 return new VcvtUFixedFpS(machInst, vd, vd, size); 1465 } 1466 } else { 1467 if (half) { 1468 return new VcvtUHFixedFpD(machInst, vd, vd, size); 1469 } else { 1470 return new VcvtUFixedFpD(machInst, vd, vd, size); 1471 } 1472 } 1473 } 1474 case 0xc: 1475 if (bits(machInst, 7) == 0) { 1476 if (single) { 1477 return new VcvtFpUIntSR(machInst, vd, vm); 1478 } else { 1479 vd = (IntRegIndex)(bits(machInst, 22) | 1480 (bits(machInst, 15, 12) << 1)); 1481 return new VcvtFpUIntDR(machInst, vd, vm); 1482 } 1483 } else { 1484 if (single) { 1485 return new VcvtFpUIntS(machInst, vd, vm); 1486 } else { 1487 vd = (IntRegIndex)(bits(machInst, 22) | 1488 (bits(machInst, 15, 12) << 1)); 1489 return new VcvtFpUIntD(machInst, vd, vm); 1490 } 1491 } 1492 case 0xd: 1493 if (bits(machInst, 7) == 0) { 1494 if (single) { 1495 return new VcvtFpSIntSR(machInst, vd, vm); 1496 } else { 1497 vd = (IntRegIndex)(bits(machInst, 22) | 1498 (bits(machInst, 15, 12) << 1)); 1499 return new VcvtFpSIntDR(machInst, vd, vm); 1500 } 1501 } else { 1502 if (single) { 1503 return new VcvtFpSIntS(machInst, vd, vm); 1504 } else { 1505 vd = (IntRegIndex)(bits(machInst, 22) | 1506 (bits(machInst, 15, 12) << 1)); 1507 return new VcvtFpSIntD(machInst, vd, vm); 1508 } 1509 } 1510 case 0xe: 1511 { 1512 const bool half = (bits(machInst, 7) == 0); 1513 const uint32_t imm = bits(machInst, 5) | 1514 (bits(machInst, 3, 0) << 1); 1515 const uint32_t size = 1516 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 1517 if (single) { 1518 if (half) { 1519 return new VcvtFpSHFixedS(machInst, vd, vd, size); 1520 } else { 1521 return new VcvtFpSFixedS(machInst, vd, vd, size); 1522 } 1523 } else { 1524 if (half) { 1525 return new VcvtFpSHFixedD(machInst, vd, vd, size); 1526 } else { 1527 return new VcvtFpSFixedD(machInst, vd, vd, size); 1528 } 1529 } 1530 } 1531 case 0xf: 1532 { 1533 const bool half = (bits(machInst, 7) == 0); 1534 const uint32_t imm = bits(machInst, 5) | 1535 (bits(machInst, 3, 0) << 1); 1536 const uint32_t size = 1537 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 1538 if (single) { 1539 if (half) { 1540 return new VcvtFpUHFixedS(machInst, vd, vd, size); 1541 } else { 1542 return new VcvtFpUFixedS(machInst, vd, vd, size); 1543 } 1544 } else { 1545 if (half) { 1546 return new VcvtFpUHFixedD(machInst, vd, vd, size); 1547 } else { 1548 return new VcvtFpUFixedD(machInst, vd, vd, size); 1549 } 1550 } 1551 } 1552 } 1553 break; 1554 } 1555 return new Unknown(machInst); 1556 } 1557 ''' 1558}}; 1559 1560def format VfpData() {{ 1561 decode_block = ''' 1562 return decodeVfpData(machInst); 1563 ''' 1564}};
| 2101 } 2102 } 2103 return new Unknown(machInst); 2104 } 2105 ''' 2106}}; 2107 2108def format ShortFpTransfer() {{ 2109 decode_block = ''' 2110 return decodeShortFpTransfer(machInst); 2111 ''' 2112}}; 2113 2114let {{ 2115 header_output = ''' 2116 StaticInstPtr 2117 decodeVfpData(ExtMachInst machInst); 2118 ''' 2119 decoder_output = ''' 2120 StaticInstPtr 2121 decodeVfpData(ExtMachInst machInst) 2122 { 2123 const uint32_t opc1 = bits(machInst, 23, 20); 2124 const uint32_t opc2 = bits(machInst, 19, 16); 2125 const uint32_t opc3 = bits(machInst, 7, 6); 2126 //const uint32_t opc4 = bits(machInst, 3, 0); 2127 const bool single = (bits(machInst, 8) == 0); 2128 // Used to select between vcmp and vcmpe. 2129 const bool e = (bits(machInst, 7) == 1); 2130 IntRegIndex vd; 2131 IntRegIndex vm; 2132 IntRegIndex vn; 2133 if (single) { 2134 vd = (IntRegIndex)(bits(machInst, 22) | 2135 (bits(machInst, 15, 12) << 1)); 2136 vm = (IntRegIndex)(bits(machInst, 5) | 2137 (bits(machInst, 3, 0) << 1)); 2138 vn = (IntRegIndex)(bits(machInst, 7) | 2139 (bits(machInst, 19, 16) << 1)); 2140 } else { 2141 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2142 (bits(machInst, 15, 12) << 1)); 2143 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2144 (bits(machInst, 3, 0) << 1)); 2145 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2146 (bits(machInst, 19, 16) << 1)); 2147 } 2148 switch (opc1 & 0xb /* 1011 */) { 2149 case 0x0: 2150 if (bits(machInst, 6) == 0) { 2151 if (single) { 2152 return decodeVfpRegRegRegOp<VmlaS>( 2153 machInst, vd, vn, vm, false); 2154 } else { 2155 return decodeVfpRegRegRegOp<VmlaD>( 2156 machInst, vd, vn, vm, true); 2157 } 2158 } else { 2159 if (single) { 2160 return decodeVfpRegRegRegOp<VmlsS>( 2161 machInst, vd, vn, vm, false); 2162 } else { 2163 return decodeVfpRegRegRegOp<VmlsD>( 2164 machInst, vd, vn, vm, true); 2165 } 2166 } 2167 case 0x1: 2168 if (bits(machInst, 6) == 1) { 2169 if (single) { 2170 return decodeVfpRegRegRegOp<VnmlaS>( 2171 machInst, vd, vn, vm, false); 2172 } else { 2173 return decodeVfpRegRegRegOp<VnmlaD>( 2174 machInst, vd, vn, vm, true); 2175 } 2176 } else { 2177 if (single) { 2178 return decodeVfpRegRegRegOp<VnmlsS>( 2179 machInst, vd, vn, vm, false); 2180 } else { 2181 return decodeVfpRegRegRegOp<VnmlsD>( 2182 machInst, vd, vn, vm, true); 2183 } 2184 } 2185 case 0x2: 2186 if ((opc3 & 0x1) == 0) { 2187 if (single) { 2188 return decodeVfpRegRegRegOp<VmulS>( 2189 machInst, vd, vn, vm, false); 2190 } else { 2191 return decodeVfpRegRegRegOp<VmulD>( 2192 machInst, vd, vn, vm, true); 2193 } 2194 } else { 2195 if (single) { 2196 return decodeVfpRegRegRegOp<VnmulS>( 2197 machInst, vd, vn, vm, false); 2198 } else { 2199 return decodeVfpRegRegRegOp<VnmulD>( 2200 machInst, vd, vn, vm, true); 2201 } 2202 } 2203 case 0x3: 2204 if ((opc3 & 0x1) == 0) { 2205 if (single) { 2206 return decodeVfpRegRegRegOp<VaddS>( 2207 machInst, vd, vn, vm, false); 2208 } else { 2209 return decodeVfpRegRegRegOp<VaddD>( 2210 machInst, vd, vn, vm, true); 2211 } 2212 } else { 2213 if (single) { 2214 return decodeVfpRegRegRegOp<VsubS>( 2215 machInst, vd, vn, vm, false); 2216 } else { 2217 return decodeVfpRegRegRegOp<VsubD>( 2218 machInst, vd, vn, vm, true); 2219 } 2220 } 2221 case 0x8: 2222 if ((opc3 & 0x1) == 0) { 2223 if (single) { 2224 return decodeVfpRegRegRegOp<VdivS>( 2225 machInst, vd, vn, vm, false); 2226 } else { 2227 return decodeVfpRegRegRegOp<VdivD>( 2228 machInst, vd, vn, vm, true); 2229 } 2230 } 2231 break; 2232 case 0xb: 2233 if ((opc3 & 0x1) == 0) { 2234 const uint32_t baseImm = 2235 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2236 if (single) { 2237 uint32_t imm = vfp_modified_imm(baseImm, false); 2238 return decodeVfpRegImmOp<VmovImmS>( 2239 machInst, vd, imm, false); 2240 } else { 2241 uint64_t imm = vfp_modified_imm(baseImm, true); 2242 return decodeVfpRegImmOp<VmovImmD>( 2243 machInst, vd, imm, true); 2244 } 2245 } 2246 switch (opc2) { 2247 case 0x0: 2248 if (opc3 == 1) { 2249 if (single) { 2250 return decodeVfpRegRegOp<VmovRegS>( 2251 machInst, vd, vm, false); 2252 } else { 2253 return decodeVfpRegRegOp<VmovRegD>( 2254 machInst, vd, vm, true); 2255 } 2256 } else { 2257 if (single) { 2258 return decodeVfpRegRegOp<VabsS>( 2259 machInst, vd, vm, false); 2260 } else { 2261 return decodeVfpRegRegOp<VabsD>( 2262 machInst, vd, vm, true); 2263 } 2264 } 2265 case 0x1: 2266 if (opc3 == 1) { 2267 if (single) { 2268 return decodeVfpRegRegOp<VnegS>( 2269 machInst, vd, vm, false); 2270 } else { 2271 return decodeVfpRegRegOp<VnegD>( 2272 machInst, vd, vm, true); 2273 } 2274 } else { 2275 if (single) { 2276 return decodeVfpRegRegOp<VsqrtS>( 2277 machInst, vd, vm, false); 2278 } else { 2279 return decodeVfpRegRegOp<VsqrtD>( 2280 machInst, vd, vm, true); 2281 } 2282 } 2283 case 0x2: 2284 case 0x3: 2285 { 2286 const bool toHalf = bits(machInst, 16); 2287 const bool top = bits(machInst, 7); 2288 if (top) { 2289 if (toHalf) { 2290 return new VcvtFpSFpHT(machInst, vd, vm); 2291 } else { 2292 return new VcvtFpHTFpS(machInst, vd, vm); 2293 } 2294 } else { 2295 if (toHalf) { 2296 return new VcvtFpSFpHB(machInst, vd, vm); 2297 } else { 2298 return new VcvtFpHBFpS(machInst, vd, vm); 2299 } 2300 } 2301 } 2302 case 0x4: 2303 if (single) { 2304 if (e) { 2305 return new VcmpeS(machInst, vd, vm); 2306 } else { 2307 return new VcmpS(machInst, vd, vm); 2308 } 2309 } else { 2310 if (e) { 2311 return new VcmpeD(machInst, vd, vm); 2312 } else { 2313 return new VcmpD(machInst, vd, vm); 2314 } 2315 } 2316 case 0x5: 2317 if (single) { 2318 if (e) { 2319 return new VcmpeZeroS(machInst, vd, 0); 2320 } else { 2321 return new VcmpZeroS(machInst, vd, 0); 2322 } 2323 } else { 2324 if (e) { 2325 return new VcmpeZeroD(machInst, vd, 0); 2326 } else { 2327 return new VcmpZeroD(machInst, vd, 0); 2328 } 2329 } 2330 case 0x7: 2331 if (opc3 == 0x3) { 2332 if (single) { 2333 vm = (IntRegIndex)(bits(machInst, 5) | 2334 (bits(machInst, 3, 0) << 1)); 2335 return new VcvtFpSFpD(machInst, vd, vm); 2336 } else { 2337 vd = (IntRegIndex)(bits(machInst, 22) | 2338 (bits(machInst, 15, 12) << 1)); 2339 return new VcvtFpDFpS(machInst, vd, vm); 2340 } 2341 } 2342 break; 2343 case 0x8: 2344 if (bits(machInst, 7) == 0) { 2345 if (single) { 2346 return new VcvtUIntFpS(machInst, vd, vm); 2347 } else { 2348 vm = (IntRegIndex)(bits(machInst, 5) | 2349 (bits(machInst, 3, 0) << 1)); 2350 return new VcvtUIntFpD(machInst, vd, vm); 2351 } 2352 } else { 2353 if (single) { 2354 return new VcvtSIntFpS(machInst, vd, vm); 2355 } else { 2356 vm = (IntRegIndex)(bits(machInst, 5) | 2357 (bits(machInst, 3, 0) << 1)); 2358 return new VcvtSIntFpD(machInst, vd, vm); 2359 } 2360 } 2361 case 0xa: 2362 { 2363 const bool half = (bits(machInst, 7) == 0); 2364 const uint32_t imm = bits(machInst, 5) | 2365 (bits(machInst, 3, 0) << 1); 2366 const uint32_t size = 2367 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2368 if (single) { 2369 if (half) { 2370 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2371 } else { 2372 return new VcvtSFixedFpS(machInst, vd, vd, size); 2373 } 2374 } else { 2375 if (half) { 2376 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2377 } else { 2378 return new VcvtSFixedFpD(machInst, vd, vd, size); 2379 } 2380 } 2381 } 2382 case 0xb: 2383 { 2384 const bool half = (bits(machInst, 7) == 0); 2385 const uint32_t imm = bits(machInst, 5) | 2386 (bits(machInst, 3, 0) << 1); 2387 const uint32_t size = 2388 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2389 if (single) { 2390 if (half) { 2391 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2392 } else { 2393 return new VcvtUFixedFpS(machInst, vd, vd, size); 2394 } 2395 } else { 2396 if (half) { 2397 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2398 } else { 2399 return new VcvtUFixedFpD(machInst, vd, vd, size); 2400 } 2401 } 2402 } 2403 case 0xc: 2404 if (bits(machInst, 7) == 0) { 2405 if (single) { 2406 return new VcvtFpUIntSR(machInst, vd, vm); 2407 } else { 2408 vd = (IntRegIndex)(bits(machInst, 22) | 2409 (bits(machInst, 15, 12) << 1)); 2410 return new VcvtFpUIntDR(machInst, vd, vm); 2411 } 2412 } else { 2413 if (single) { 2414 return new VcvtFpUIntS(machInst, vd, vm); 2415 } else { 2416 vd = (IntRegIndex)(bits(machInst, 22) | 2417 (bits(machInst, 15, 12) << 1)); 2418 return new VcvtFpUIntD(machInst, vd, vm); 2419 } 2420 } 2421 case 0xd: 2422 if (bits(machInst, 7) == 0) { 2423 if (single) { 2424 return new VcvtFpSIntSR(machInst, vd, vm); 2425 } else { 2426 vd = (IntRegIndex)(bits(machInst, 22) | 2427 (bits(machInst, 15, 12) << 1)); 2428 return new VcvtFpSIntDR(machInst, vd, vm); 2429 } 2430 } else { 2431 if (single) { 2432 return new VcvtFpSIntS(machInst, vd, vm); 2433 } else { 2434 vd = (IntRegIndex)(bits(machInst, 22) | 2435 (bits(machInst, 15, 12) << 1)); 2436 return new VcvtFpSIntD(machInst, vd, vm); 2437 } 2438 } 2439 case 0xe: 2440 { 2441 const bool half = (bits(machInst, 7) == 0); 2442 const uint32_t imm = bits(machInst, 5) | 2443 (bits(machInst, 3, 0) << 1); 2444 const uint32_t size = 2445 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2446 if (single) { 2447 if (half) { 2448 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2449 } else { 2450 return new VcvtFpSFixedS(machInst, vd, vd, size); 2451 } 2452 } else { 2453 if (half) { 2454 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2455 } else { 2456 return new VcvtFpSFixedD(machInst, vd, vd, size); 2457 } 2458 } 2459 } 2460 case 0xf: 2461 { 2462 const bool half = (bits(machInst, 7) == 0); 2463 const uint32_t imm = bits(machInst, 5) | 2464 (bits(machInst, 3, 0) << 1); 2465 const uint32_t size = 2466 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2467 if (single) { 2468 if (half) { 2469 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2470 } else { 2471 return new VcvtFpUFixedS(machInst, vd, vd, size); 2472 } 2473 } else { 2474 if (half) { 2475 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2476 } else { 2477 return new VcvtFpUFixedD(machInst, vd, vd, size); 2478 } 2479 } 2480 } 2481 } 2482 break; 2483 } 2484 return new Unknown(machInst); 2485 } 2486 ''' 2487}}; 2488 2489def format VfpData() {{ 2490 decode_block = ''' 2491 return decodeVfpData(machInst); 2492 ''' 2493}};
|