fp.isa (8303:5a95f1d2494e) fp.isa (8607:5fb918115c07)
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
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);
108 const bool single = bits(machInst, 23);
109 const bool singleAll = single && (bits(b, 3, 2) == 3);
110 const bool load = bits(machInst, 21);
111
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 = TLB::MustBeOne;
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;
159 } else {
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;
183 }
184 break;
185 }
186 } else {
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;
224 }
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;
238 break;
239 case 2:
240 if (bits(indexAlign, 0))
241 align = (4 << bits(indexAlign, 1, 0)) - 1;
242 break;
243 }
244 break;
245 }
246 }
247 if (size == 0x3) {
248 return new Unknown(machInst);
249 }
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 {
324 // Store instructions.
325 if (single) {
326 if (singleAll) {
327 return new Unknown(machInst);
328 } else {
329 return new VstSingle(machInst, false, width, rn, vd,
330 regs, inc, size, align, rm, lane);
331 }
332 } else {
333 return new VstMult(machInst, width, rn, vd,
334 regs, inc, size, align, rm);
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);
362 switch (a) {
363 case 0x0:
364 if (b) {
365 if (u) {
366 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
367 q, size, machInst, vd, vn, vm);
368 } else {
369 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
370 q, size, machInst, vd, vn, vm);
371 }
372 } else {
373 if (size == 3)
374 return new Unknown(machInst);
375 return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
376 q, u, size, machInst, vd, vn, vm);
377 }
378 case 0x1:
379 if (!b) {
380 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
381 q, u, size, machInst, vd, vn, vm);
382 } else {
383 if (u) {
384 switch (c) {
385 case 0:
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 }
391 case 1:
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 }
397 case 2:
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 }
403 case 3:
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 }
409 }
410 } else {
411 switch (c) {
412 case 0:
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 }
418 case 1:
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 }
424 case 2:
425 if (vn == vm) {
426 if (q) {
427 return new VmovQ<uint64_t>(
428 machInst, vd, vn, vm);
429 } else {
430 return new VmovD<uint64_t>(
431 machInst, vd, vn, vm);
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 }
441 }
442 case 3:
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 }
450 }
451 }
452 }
453 case 0x2:
454 if (b) {
455 if (u) {
456 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
457 q, size, machInst, vd, vn, vm);
458 } else {
459 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
460 q, size, machInst, vd, vn, vm);
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);
467 }
468 case 0x3:
469 if (b) {
470 return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
471 q, u, size, machInst, vd, vn, vm);
472 } else {
473 return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
474 q, u, size, machInst, vd, vn, vm);
475 }
476 case 0x4:
477 if (b) {
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 }
485 } else {
486 return decodeNeonUSThreeReg<VshlD, VshlQ>(
487 q, u, size, machInst, vd, vm, vn);
488 }
489 case 0x5:
490 if (b) {
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 }
498 } else {
499 return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
500 q, u, size, machInst, vd, vm, vn);
501 }
502 case 0x6:
503 if (b) {
504 return decodeNeonUSThreeReg<VminD, VminQ>(
505 q, u, size, machInst, vd, vn, vm);
506 } else {
507 return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
508 q, u, size, machInst, vd, vn, vm);
509 }
510 case 0x7:
511 if (b) {
512 return decodeNeonUSThreeReg<VabaD, VabaQ>(
513 q, u, size, machInst, vd, vn, vm);
514 } else {
515 if (bits(machInst, 23) == 1) {
516 if (q) {
517 return new Unknown(machInst);
518 } else {
519 return decodeNeonUSThreeUSReg<Vabdl>(
520 u, size, machInst, vd, vn, vm);
521 }
522 } else {
523 return decodeNeonUSThreeReg<VabdD, VabdQ>(
524 q, u, size, machInst, vd, vn, vm);
525 }
526 }
527 case 0x8:
528 if (b) {
529 if (u) {
530 return decodeNeonUThreeReg<VceqD, VceqQ>(
531 q, size, machInst, vd, vn, vm);
532 } else {
533 return decodeNeonUThreeReg<VtstD, VtstQ>(
534 q, size, machInst, vd, vn, vm);
535 }
536 } else {
537 if (u) {
538 return decodeNeonUThreeReg<NVsubD, NVsubQ>(
539 q, size, machInst, vd, vn, vm);
540 } else {
541 return decodeNeonUThreeReg<NVaddD, NVaddQ>(
542 q, size, machInst, vd, vn, vm);
543 }
544 }
545 case 0x9:
546 if (b) {
547 if (u) {
548 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
549 q, size, machInst, vd, vn, vm);
550 } else {
551 return decodeNeonSThreeReg<NVmulD, NVmulQ>(
552 q, size, machInst, vd, vn, vm);
553 }
554 } else {
555 if (u) {
556 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
557 q, u, size, machInst, vd, vn, vm);
558 } else {
559 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
560 q, u, size, machInst, vd, vn, vm);
561 }
562 }
563 case 0xa:
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
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);
108 const bool single = bits(machInst, 23);
109 const bool singleAll = single && (bits(b, 3, 2) == 3);
110 const bool load = bits(machInst, 21);
111
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 = TLB::MustBeOne;
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;
159 } else {
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;
183 }
184 break;
185 }
186 } else {
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;
224 }
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;
238 break;
239 case 2:
240 if (bits(indexAlign, 0))
241 align = (4 << bits(indexAlign, 1, 0)) - 1;
242 break;
243 }
244 break;
245 }
246 }
247 if (size == 0x3) {
248 return new Unknown(machInst);
249 }
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 {
324 // Store instructions.
325 if (single) {
326 if (singleAll) {
327 return new Unknown(machInst);
328 } else {
329 return new VstSingle(machInst, false, width, rn, vd,
330 regs, inc, size, align, rm, lane);
331 }
332 } else {
333 return new VstMult(machInst, width, rn, vd,
334 regs, inc, size, align, rm);
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);
362 switch (a) {
363 case 0x0:
364 if (b) {
365 if (u) {
366 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
367 q, size, machInst, vd, vn, vm);
368 } else {
369 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
370 q, size, machInst, vd, vn, vm);
371 }
372 } else {
373 if (size == 3)
374 return new Unknown(machInst);
375 return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
376 q, u, size, machInst, vd, vn, vm);
377 }
378 case 0x1:
379 if (!b) {
380 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
381 q, u, size, machInst, vd, vn, vm);
382 } else {
383 if (u) {
384 switch (c) {
385 case 0:
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 }
391 case 1:
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 }
397 case 2:
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 }
403 case 3:
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 }
409 }
410 } else {
411 switch (c) {
412 case 0:
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 }
418 case 1:
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 }
424 case 2:
425 if (vn == vm) {
426 if (q) {
427 return new VmovQ<uint64_t>(
428 machInst, vd, vn, vm);
429 } else {
430 return new VmovD<uint64_t>(
431 machInst, vd, vn, vm);
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 }
441 }
442 case 3:
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 }
450 }
451 }
452 }
453 case 0x2:
454 if (b) {
455 if (u) {
456 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
457 q, size, machInst, vd, vn, vm);
458 } else {
459 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
460 q, size, machInst, vd, vn, vm);
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);
467 }
468 case 0x3:
469 if (b) {
470 return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
471 q, u, size, machInst, vd, vn, vm);
472 } else {
473 return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
474 q, u, size, machInst, vd, vn, vm);
475 }
476 case 0x4:
477 if (b) {
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 }
485 } else {
486 return decodeNeonUSThreeReg<VshlD, VshlQ>(
487 q, u, size, machInst, vd, vm, vn);
488 }
489 case 0x5:
490 if (b) {
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 }
498 } else {
499 return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
500 q, u, size, machInst, vd, vm, vn);
501 }
502 case 0x6:
503 if (b) {
504 return decodeNeonUSThreeReg<VminD, VminQ>(
505 q, u, size, machInst, vd, vn, vm);
506 } else {
507 return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
508 q, u, size, machInst, vd, vn, vm);
509 }
510 case 0x7:
511 if (b) {
512 return decodeNeonUSThreeReg<VabaD, VabaQ>(
513 q, u, size, machInst, vd, vn, vm);
514 } else {
515 if (bits(machInst, 23) == 1) {
516 if (q) {
517 return new Unknown(machInst);
518 } else {
519 return decodeNeonUSThreeUSReg<Vabdl>(
520 u, size, machInst, vd, vn, vm);
521 }
522 } else {
523 return decodeNeonUSThreeReg<VabdD, VabdQ>(
524 q, u, size, machInst, vd, vn, vm);
525 }
526 }
527 case 0x8:
528 if (b) {
529 if (u) {
530 return decodeNeonUThreeReg<VceqD, VceqQ>(
531 q, size, machInst, vd, vn, vm);
532 } else {
533 return decodeNeonUThreeReg<VtstD, VtstQ>(
534 q, size, machInst, vd, vn, vm);
535 }
536 } else {
537 if (u) {
538 return decodeNeonUThreeReg<NVsubD, NVsubQ>(
539 q, size, machInst, vd, vn, vm);
540 } else {
541 return decodeNeonUThreeReg<NVaddD, NVaddQ>(
542 q, size, machInst, vd, vn, vm);
543 }
544 }
545 case 0x9:
546 if (b) {
547 if (u) {
548 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
549 q, size, machInst, vd, vn, vm);
550 } else {
551 return decodeNeonSThreeReg<NVmulD, NVmulQ>(
552 q, size, machInst, vd, vn, vm);
553 }
554 } else {
555 if (u) {
556 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
557 q, u, size, machInst, vd, vn, vm);
558 } else {
559 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
560 q, u, size, machInst, vd, vn, vm);
561 }
562 }
563 case 0xa:
564 if (q)
565 return new Unknown(machInst);
564 if (b) {
566 if (b) {
565 return decodeNeonUSThreeReg<VpminD, VpminQ>(
566 q, u, size, machInst, vd, vn, vm);
567 return decodeNeonUSThreeUSReg<VpminD>(
568 u, size, machInst, vd, vn, vm);
567 } else {
569 } else {
568 return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>(
569 q, u, size, machInst, vd, vn, vm);
570 return decodeNeonUSThreeUSReg<VpmaxD>(
571 u, size, machInst, vd, vn, vm);
570 }
571 case 0xb:
572 if (b) {
572 }
573 case 0xb:
574 if (b) {
573 if (u) {
575 if (u || q) {
574 return new Unknown(machInst);
575 } else {
576 return new Unknown(machInst);
577 } else {
576 return decodeNeonUThreeReg<NVpaddD, NVpaddQ>(
577 q, size, machInst, vd, vn, vm);
578 return decodeNeonUThreeUSReg<NVpaddD>(
579 size, machInst, vd, vn, vm);
578 }
579 } else {
580 if (u) {
581 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
582 q, size, machInst, vd, vn, vm);
583 } else {
584 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
585 q, size, machInst, vd, vn, vm);
586 }
587 }
588 case 0xc:
589 return new Unknown(machInst);
590 case 0xd:
591 if (b) {
592 if (u) {
593 if (bits(c, 1) == 0) {
594 if (q) {
595 return new NVmulQFp<float>(machInst, vd, vn, vm);
596 } else {
597 return new NVmulDFp<float>(machInst, vd, vn, vm);
598 }
599 } else {
600 return new Unknown(machInst);
601 }
602 } else {
603 if (bits(c, 1) == 0) {
604 if (q) {
605 return new NVmlaQFp<float>(machInst, vd, vn, vm);
606 } else {
607 return new NVmlaDFp<float>(machInst, vd, vn, vm);
608 }
609 } else {
610 if (q) {
611 return new NVmlsQFp<float>(machInst, vd, vn, vm);
612 } else {
613 return new NVmlsDFp<float>(machInst, vd, vn, vm);
614 }
615 }
616 }
617 } else {
618 if (u) {
619 if (bits(c, 1) == 0) {
620 if (q) {
621 return new VpaddQFp<float>(machInst, vd, vn, vm);
622 } else {
623 return new VpaddDFp<float>(machInst, vd, vn, vm);
624 }
625 } else {
626 if (q) {
627 return new VabdQFp<float>(machInst, vd, vn, vm);
628 } else {
629 return new VabdDFp<float>(machInst, vd, vn, vm);
630 }
631 }
632 } else {
633 if (bits(c, 1) == 0) {
634 if (q) {
635 return new VaddQFp<float>(machInst, vd, vn, vm);
636 } else {
637 return new VaddDFp<float>(machInst, vd, vn, vm);
638 }
639 } else {
640 if (q) {
641 return new VsubQFp<float>(machInst, vd, vn, vm);
642 } else {
643 return new VsubDFp<float>(machInst, vd, vn, vm);
644 }
645 }
646 }
647 }
648 case 0xe:
649 if (b) {
650 if (u) {
651 if (bits(c, 1) == 0) {
652 if (q) {
653 return new VacgeQFp<float>(machInst, vd, vn, vm);
654 } else {
655 return new VacgeDFp<float>(machInst, vd, vn, vm);
656 }
657 } else {
658 if (q) {
659 return new VacgtQFp<float>(machInst, vd, vn, vm);
660 } else {
661 return new VacgtDFp<float>(machInst, vd, vn, vm);
662 }
663 }
664 } else {
665 return new Unknown(machInst);
666 }
667 } else {
668 if (u) {
669 if (bits(c, 1) == 0) {
670 if (q) {
671 return new VcgeQFp<float>(machInst, vd, vn, vm);
672 } else {
673 return new VcgeDFp<float>(machInst, vd, vn, vm);
674 }
675 } else {
676 if (q) {
677 return new VcgtQFp<float>(machInst, vd, vn, vm);
678 } else {
679 return new VcgtDFp<float>(machInst, vd, vn, vm);
680 }
681 }
682 } else {
683 if (bits(c, 1) == 0) {
684 if (q) {
685 return new VceqQFp<float>(machInst, vd, vn, vm);
686 } else {
687 return new VceqDFp<float>(machInst, vd, vn, vm);
688 }
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) {
700 if (q) {
701 return new VrecpsQFp<float>(machInst, vd, vn, vm);
702 } else {
703 return new VrecpsDFp<float>(machInst, vd, vn, vm);
704 }
705 } else {
706 if (q) {
707 return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
708 } else {
709 return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
710 }
711 }
712 }
713 } else {
714 if (u) {
715 if (bits(c, 1) == 0) {
716 if (q) {
717 return new VpmaxQFp<float>(machInst, vd, vn, vm);
718 } else {
719 return new VpmaxDFp<float>(machInst, vd, vn, vm);
720 }
721 } else {
722 if (q) {
723 return new VpminQFp<float>(machInst, vd, vn, vm);
724 } else {
725 return new VpminDFp<float>(machInst, vd, vn, vm);
726 }
727 }
728 } else {
729 if (bits(c, 1) == 0) {
730 if (q) {
731 return new VmaxQFp<float>(machInst, vd, vn, vm);
732 } else {
733 return new VmaxDFp<float>(machInst, vd, vn, vm);
734 }
735 } else {
736 if (q) {
737 return new VminQFp<float>(machInst, vd, vn, vm);
738 } else {
739 return new VminDFp<float>(machInst, vd, vn, vm);
740 }
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);
755 const bool op = bits(machInst, 5);
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
762 // Check for invalid immediate encodings and return an unknown op
763 // if it happens
764 bool immValid = true;
765 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
766 if (!immValid) {
767 return new Unknown(machInst);
768 }
769
770 if (op) {
771 if (bits(cmode, 3) == 0) {
772 if (bits(cmode, 0) == 0) {
773 if (q)
774 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
775 else
776 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
777 } else {
778 if (q)
779 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
780 else
781 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
782 }
783 } else {
784 if (bits(cmode, 2) == 1) {
785 switch (bits(cmode, 1, 0)) {
786 case 0:
787 case 1:
788 if (q)
789 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
790 else
791 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
792 case 2:
793 if (q)
794 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
795 else
796 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
797 case 3:
798 if (q)
799 return new Unknown(machInst);
800 else
801 return new Unknown(machInst);
802 }
803 } else {
804 if (bits(cmode, 0) == 0) {
805 if (q)
806 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
807 else
808 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
809 } else {
810 if (q)
811 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
812 else
813 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
814 }
815 }
816 }
817 } else {
818 if (bits(cmode, 3) == 0) {
819 if (bits(cmode, 0) == 0) {
820 if (q)
821 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
822 else
823 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
824 } else {
825 if (q)
826 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
827 else
828 return new NVorriD<uint64_t>(machInst, vd, bigImm);
829 }
830 } else {
831 if (bits(cmode, 2) == 1) {
832 if (q)
833 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
834 else
835 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
836 } else {
837 if (bits(cmode, 0) == 0) {
838 if (q)
839 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
840 else
841 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
842 } else {
843 if (q)
844 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
845 else
846 return new NVorriD<uint64_t>(machInst, vd, bigImm);
847 }
848 }
849 }
850 }
851 return new Unknown(machInst);
852 }
853
854 static StaticInstPtr
855 decodeNeonTwoRegAndShift(ExtMachInst machInst)
856 {
857 const uint32_t a = bits(machInst, 11, 8);
858 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
859 const bool b = bits(machInst, 6);
860 const bool l = bits(machInst, 7);
861 const IntRegIndex vd =
862 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
863 (bits(machInst, 22) << 4)));
864 const IntRegIndex vm =
865 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
866 (bits(machInst, 5) << 4)));
867 unsigned imm6 = bits(machInst, 21, 16);
868 unsigned imm = ((l ? 1 : 0) << 6) | imm6;
869 unsigned size = 3;
870 unsigned lShiftAmt = 0;
871 unsigned bitSel;
872 for (bitSel = 1 << 6; true; bitSel >>= 1) {
873 if (bitSel & imm)
874 break;
875 else if (!size)
876 return new Unknown(machInst);
877 size--;
878 }
879 lShiftAmt = imm6 & ~bitSel;
880 unsigned rShiftAmt = 0;
881 if (a != 0xe && a != 0xf) {
882 if (size > 2)
883 rShiftAmt = 64 - imm6;
884 else
885 rShiftAmt = 2 * (8 << size) - imm6;
886 }
887
888 switch (a) {
889 case 0x0:
890 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
891 b, u, size, machInst, vd, vm, rShiftAmt);
892 case 0x1:
893 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
894 b, u, size, machInst, vd, vm, rShiftAmt);
895 case 0x2:
896 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
897 b, u, size, machInst, vd, vm, rShiftAmt);
898 case 0x3:
899 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
900 b, u, size, machInst, vd, vm, rShiftAmt);
901 case 0x4:
902 if (u) {
903 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
904 b, size, machInst, vd, vm, rShiftAmt);
905 } else {
906 return new Unknown(machInst);
907 }
908 case 0x5:
909 if (u) {
910 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
911 b, size, machInst, vd, vm, lShiftAmt);
912 } else {
913 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
914 b, size, machInst, vd, vm, lShiftAmt);
915 }
916 case 0x6:
917 case 0x7:
918 if (u) {
919 if (a == 0x6) {
920 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
921 b, size, machInst, vd, vm, lShiftAmt);
922 } else {
923 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
924 b, size, machInst, vd, vm, lShiftAmt);
925 }
926 } else {
927 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
928 b, size, machInst, vd, vm, lShiftAmt);
929 }
930 case 0x8:
931 if (l) {
932 return new Unknown(machInst);
933 } else if (u) {
934 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
935 b, size, machInst, vd, vm, rShiftAmt);
936 } else {
937 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
938 b, size, machInst, vd, vm, rShiftAmt);
939 }
940 case 0x9:
941 if (l) {
942 return new Unknown(machInst);
943 } else if (u) {
944 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
945 b, size, machInst, vd, vm, rShiftAmt);
946 } else {
947 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
948 b, size, machInst, vd, vm, rShiftAmt);
949 }
950 case 0xa:
951 if (l || b) {
952 return new Unknown(machInst);
953 } else {
954 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
955 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
956 }
957 case 0xe:
958 if (l) {
959 return new Unknown(machInst);
960 } else {
961 if (bits(imm6, 5) == 0)
962 return new Unknown(machInst);
963 if (u) {
964 if (b) {
965 return new NVcvtu2fpQ<float>(
966 machInst, vd, vm, 64 - imm6);
967 } else {
968 return new NVcvtu2fpD<float>(
969 machInst, vd, vm, 64 - imm6);
970 }
971 } else {
972 if (b) {
973 return new NVcvts2fpQ<float>(
974 machInst, vd, vm, 64 - imm6);
975 } else {
976 return new NVcvts2fpD<float>(
977 machInst, vd, vm, 64 - imm6);
978 }
979 }
980 }
981 case 0xf:
982 if (l) {
983 return new Unknown(machInst);
984 } else {
985 if (bits(imm6, 5) == 0)
986 return new Unknown(machInst);
987 if (u) {
988 if (b) {
989 return new NVcvt2ufxQ<float>(
990 machInst, vd, vm, 64 - imm6);
991 } else {
992 return new NVcvt2ufxD<float>(
993 machInst, vd, vm, 64 - imm6);
994 }
995 } else {
996 if (b) {
997 return new NVcvt2sfxQ<float>(
998 machInst, vd, vm, 64 - imm6);
999 } else {
1000 return new NVcvt2sfxD<float>(
1001 machInst, vd, vm, 64 - imm6);
1002 }
1003 }
1004 }
1005 }
1006 return new Unknown(machInst);
1007 }
1008
1009 static StaticInstPtr
1010 decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1011 {
1012 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1013 const uint32_t a = bits(machInst, 11, 8);
1014 const IntRegIndex vd =
1015 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1016 (bits(machInst, 22) << 4)));
1017 const IntRegIndex vn =
1018 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1019 (bits(machInst, 7) << 4)));
1020 const IntRegIndex vm =
1021 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1022 (bits(machInst, 5) << 4)));
1023 const unsigned size = bits(machInst, 21, 20);
1024 switch (a) {
1025 case 0x0:
1026 return decodeNeonUSThreeUSReg<Vaddl>(
1027 u, size, machInst, vd, vn, vm);
1028 case 0x1:
1029 return decodeNeonUSThreeUSReg<Vaddw>(
1030 u, size, machInst, vd, vn, vm);
1031 case 0x2:
1032 return decodeNeonUSThreeUSReg<Vsubl>(
1033 u, size, machInst, vd, vn, vm);
1034 case 0x3:
1035 return decodeNeonUSThreeUSReg<Vsubw>(
1036 u, size, machInst, vd, vn, vm);
1037 case 0x4:
1038 if (u) {
1039 return decodeNeonUThreeUSReg<Vraddhn>(
1040 size, machInst, vd, vn, vm);
1041 } else {
1042 return decodeNeonUThreeUSReg<Vaddhn>(
1043 size, machInst, vd, vn, vm);
1044 }
1045 case 0x5:
1046 return decodeNeonUSThreeUSReg<Vabal>(
1047 u, size, machInst, vd, vn, vm);
1048 case 0x6:
1049 if (u) {
1050 return decodeNeonUThreeUSReg<Vrsubhn>(
1051 size, machInst, vd, vn, vm);
1052 } else {
1053 return decodeNeonUThreeUSReg<Vsubhn>(
1054 size, machInst, vd, vn, vm);
1055 }
1056 case 0x7:
1057 if (bits(machInst, 23)) {
1058 return decodeNeonUSThreeUSReg<Vabdl>(
1059 u, size, machInst, vd, vn, vm);
1060 } else {
1061 return decodeNeonUSThreeReg<VabdD, VabdQ>(
1062 bits(machInst, 6), u, size, machInst, vd, vn, vm);
1063 }
1064 case 0x8:
1065 return decodeNeonUSThreeUSReg<Vmlal>(
1066 u, size, machInst, vd, vn, vm);
1067 case 0xa:
1068 return decodeNeonUSThreeUSReg<Vmlsl>(
1069 u, size, machInst, vd, vn, vm);
1070 case 0x9:
1071 if (u) {
1072 return new Unknown(machInst);
1073 } else {
1074 return decodeNeonSThreeUSReg<Vqdmlal>(
1075 size, machInst, vd, vn, vm);
1076 }
1077 case 0xb:
1078 if (u) {
1079 return new Unknown(machInst);
1080 } else {
1081 return decodeNeonSThreeUSReg<Vqdmlsl>(
1082 size, machInst, vd, vn, vm);
1083 }
1084 case 0xc:
1085 return decodeNeonUSThreeUSReg<Vmull>(
1086 u, size, machInst, vd, vn, vm);
1087 case 0xd:
1088 if (u) {
1089 return new Unknown(machInst);
1090 } else {
1091 return decodeNeonSThreeUSReg<Vqdmull>(
1092 size, machInst, vd, vn, vm);
1093 }
1094 case 0xe:
1095 return decodeNeonUThreeUSReg<Vmullp>(
1096 size, machInst, vd, vn, vm);
1097 }
1098 return new Unknown(machInst);
1099 }
1100
1101 static StaticInstPtr
1102 decodeNeonTwoRegScalar(ExtMachInst machInst)
1103 {
1104 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1105 const uint32_t a = bits(machInst, 11, 8);
1106 const unsigned size = bits(machInst, 21, 20);
1107 const IntRegIndex vd =
1108 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1109 (bits(machInst, 22) << 4)));
1110 const IntRegIndex vn =
1111 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1112 (bits(machInst, 7) << 4)));
1113 const IntRegIndex vm = (size == 2) ?
1114 (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1115 (IntRegIndex)(2 * bits(machInst, 2, 0));
1116 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1117 (bits(machInst, 3) | (bits(machInst, 5) << 1));
1118 switch (a) {
1119 case 0x0:
1120 if (u) {
1121 switch (size) {
1122 case 1:
1123 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1124 case 2:
1125 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1126 default:
1127 return new Unknown(machInst);
1128 }
1129 } else {
1130 switch (size) {
1131 case 1:
1132 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1133 case 2:
1134 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1135 default:
1136 return new Unknown(machInst);
1137 }
1138 }
1139 case 0x1:
1140 if (u)
1141 return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1142 else
1143 return new VmlasDFp<float>(machInst, vd, vn, vm, index);
1144 case 0x4:
1145 if (u) {
1146 switch (size) {
1147 case 1:
1148 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1149 case 2:
1150 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1151 default:
1152 return new Unknown(machInst);
1153 }
1154 } else {
1155 switch (size) {
1156 case 1:
1157 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1158 case 2:
1159 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1160 default:
1161 return new Unknown(machInst);
1162 }
1163 }
1164 case 0x5:
1165 if (u)
1166 return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1167 else
1168 return new VmlssDFp<float>(machInst, vd, vn, vm, index);
1169 case 0x2:
1170 if (u) {
1171 switch (size) {
1172 case 1:
1173 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1174 case 2:
1175 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1176 default:
1177 return new Unknown(machInst);
1178 }
1179 } else {
1180 switch (size) {
1181 case 1:
1182 return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1183 case 2:
1184 return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1185 default:
1186 return new Unknown(machInst);
1187 }
1188 }
1189 case 0x6:
1190 if (u) {
1191 switch (size) {
1192 case 1:
1193 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1194 case 2:
1195 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1196 default:
1197 return new Unknown(machInst);
1198 }
1199 } else {
1200 switch (size) {
1201 case 1:
1202 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1203 case 2:
1204 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1205 default:
1206 return new Unknown(machInst);
1207 }
1208 }
1209 case 0x3:
1210 if (u) {
1211 return new Unknown(machInst);
1212 } else {
1213 switch (size) {
1214 case 1:
1215 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1216 case 2:
1217 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1218 default:
1219 return new Unknown(machInst);
1220 }
1221 }
1222 case 0x7:
1223 if (u) {
1224 return new Unknown(machInst);
1225 } else {
1226 switch (size) {
1227 case 1:
1228 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1229 case 2:
1230 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1231 default:
1232 return new Unknown(machInst);
1233 }
1234 }
1235 case 0x8:
1236 if (u) {
1237 switch (size) {
1238 case 1:
1239 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1240 case 2:
1241 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1242 default:
1243 return new Unknown(machInst);
1244 }
1245 } else {
1246 switch (size) {
1247 case 1:
1248 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1249 case 2:
1250 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1251 default:
1252 return new Unknown(machInst);
1253 }
1254 }
1255 case 0x9:
1256 if (u)
1257 return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1258 else
1259 return new VmulsDFp<float>(machInst, vd, vn, vm, index);
1260 case 0xa:
1261 if (u) {
1262 switch (size) {
1263 case 1:
1264 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1265 case 2:
1266 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1267 default:
1268 return new Unknown(machInst);
1269 }
1270 } else {
1271 switch (size) {
1272 case 1:
1273 return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1274 case 2:
1275 return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1276 default:
1277 return new Unknown(machInst);
1278 }
1279 }
1280 case 0xb:
1281 if (u) {
1282 return new Unknown(machInst);
1283 } else {
1284 if (u) {
1285 switch (size) {
1286 case 1:
1287 return new Vqdmulls<uint16_t>(
1288 machInst, vd, vn, vm, index);
1289 case 2:
1290 return new Vqdmulls<uint32_t>(
1291 machInst, vd, vn, vm, index);
1292 default:
1293 return new Unknown(machInst);
1294 }
1295 } else {
1296 switch (size) {
1297 case 1:
1298 return new Vqdmulls<int16_t>(
1299 machInst, vd, vn, vm, index);
1300 case 2:
1301 return new Vqdmulls<int32_t>(
1302 machInst, vd, vn, vm, index);
1303 default:
1304 return new Unknown(machInst);
1305 }
1306 }
1307 }
1308 case 0xc:
1309 if (u) {
1310 switch (size) {
1311 case 1:
1312 return new VqdmulhsQ<int16_t>(
1313 machInst, vd, vn, vm, index);
1314 case 2:
1315 return new VqdmulhsQ<int32_t>(
1316 machInst, vd, vn, vm, index);
1317 default:
1318 return new Unknown(machInst);
1319 }
1320 } else {
1321 switch (size) {
1322 case 1:
1323 return new VqdmulhsD<int16_t>(
1324 machInst, vd, vn, vm, index);
1325 case 2:
1326 return new VqdmulhsD<int32_t>(
1327 machInst, vd, vn, vm, index);
1328 default:
1329 return new Unknown(machInst);
1330 }
1331 }
1332 case 0xd:
1333 if (u) {
1334 switch (size) {
1335 case 1:
1336 return new VqrdmulhsQ<int16_t>(
1337 machInst, vd, vn, vm, index);
1338 case 2:
1339 return new VqrdmulhsQ<int32_t>(
1340 machInst, vd, vn, vm, index);
1341 default:
1342 return new Unknown(machInst);
1343 }
1344 } else {
1345 switch (size) {
1346 case 1:
1347 return new VqrdmulhsD<int16_t>(
1348 machInst, vd, vn, vm, index);
1349 case 2:
1350 return new VqrdmulhsD<int32_t>(
1351 machInst, vd, vn, vm, index);
1352 default:
1353 return new Unknown(machInst);
1354 }
1355 }
1356 }
1357 return new Unknown(machInst);
1358 }
1359
1360 static StaticInstPtr
1361 decodeNeonTwoRegMisc(ExtMachInst machInst)
1362 {
1363 const uint32_t a = bits(machInst, 17, 16);
1364 const uint32_t b = bits(machInst, 10, 6);
1365 const bool q = bits(machInst, 6);
1366 const IntRegIndex vd =
1367 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1368 (bits(machInst, 22) << 4)));
1369 const IntRegIndex vm =
1370 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1371 (bits(machInst, 5) << 4)));
1372 const unsigned size = bits(machInst, 19, 18);
1373 switch (a) {
1374 case 0x0:
1375 switch (bits(b, 4, 1)) {
1376 case 0x0:
1377 switch (size) {
1378 case 0:
1379 if (q) {
1380 return new NVrev64Q<uint8_t>(machInst, vd, vm);
1381 } else {
1382 return new NVrev64D<uint8_t>(machInst, vd, vm);
1383 }
1384 case 1:
1385 if (q) {
1386 return new NVrev64Q<uint16_t>(machInst, vd, vm);
1387 } else {
1388 return new NVrev64D<uint16_t>(machInst, vd, vm);
1389 }
1390 case 2:
1391 if (q) {
1392 return new NVrev64Q<uint32_t>(machInst, vd, vm);
1393 } else {
1394 return new NVrev64D<uint32_t>(machInst, vd, vm);
1395 }
1396 default:
1397 return new Unknown(machInst);
1398 }
1399 case 0x1:
1400 switch (size) {
1401 case 0:
1402 if (q) {
1403 return new NVrev32Q<uint8_t>(machInst, vd, vm);
1404 } else {
1405 return new NVrev32D<uint8_t>(machInst, vd, vm);
1406 }
1407 case 1:
1408 if (q) {
1409 return new NVrev32Q<uint16_t>(machInst, vd, vm);
1410 } else {
1411 return new NVrev32D<uint16_t>(machInst, vd, vm);
1412 }
1413 default:
1414 return new Unknown(machInst);
1415 }
1416 case 0x2:
1417 if (size != 0) {
1418 return new Unknown(machInst);
1419 } else if (q) {
1420 return new NVrev16Q<uint8_t>(machInst, vd, vm);
1421 } else {
1422 return new NVrev16D<uint8_t>(machInst, vd, vm);
1423 }
1424 case 0x4:
1425 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1426 q, size, machInst, vd, vm);
1427 case 0x5:
1428 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1429 q, size, machInst, vd, vm);
1430 case 0x8:
1431 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1432 q, size, machInst, vd, vm);
1433 case 0x9:
1434 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1435 q, size, machInst, vd, vm);
1436 case 0xa:
1437 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1438 q, size, machInst, vd, vm);
1439 case 0xb:
1440 if (q)
1441 return new NVmvnQ<uint64_t>(machInst, vd, vm);
1442 else
1443 return new NVmvnD<uint64_t>(machInst, vd, vm);
1444 case 0xc:
1445 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1446 q, size, machInst, vd, vm);
1447 case 0xd:
1448 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1449 q, size, machInst, vd, vm);
1450 case 0xe:
1451 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1452 q, size, machInst, vd, vm);
1453 case 0xf:
1454 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1455 q, size, machInst, vd, vm);
1456 default:
1457 return new Unknown(machInst);
1458 }
1459 case 0x1:
1460 switch (bits(b, 3, 1)) {
1461 case 0x0:
1462 if (bits(b, 4)) {
1463 if (q) {
1464 return new NVcgtQFp<float>(machInst, vd, vm);
1465 } else {
1466 return new NVcgtDFp<float>(machInst, vd, vm);
1467 }
1468 } else {
1469 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1470 q, size, machInst, vd, vm);
1471 }
1472 case 0x1:
1473 if (bits(b, 4)) {
1474 if (q) {
1475 return new NVcgeQFp<float>(machInst, vd, vm);
1476 } else {
1477 return new NVcgeDFp<float>(machInst, vd, vm);
1478 }
1479 } else {
1480 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1481 q, size, machInst, vd, vm);
1482 }
1483 case 0x2:
1484 if (bits(b, 4)) {
1485 if (q) {
1486 return new NVceqQFp<float>(machInst, vd, vm);
1487 } else {
1488 return new NVceqDFp<float>(machInst, vd, vm);
1489 }
1490 } else {
1491 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1492 q, size, machInst, vd, vm);
1493 }
1494 case 0x3:
1495 if (bits(b, 4)) {
1496 if (q) {
1497 return new NVcleQFp<float>(machInst, vd, vm);
1498 } else {
1499 return new NVcleDFp<float>(machInst, vd, vm);
1500 }
1501 } else {
1502 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1503 q, size, machInst, vd, vm);
1504 }
1505 case 0x4:
1506 if (bits(b, 4)) {
1507 if (q) {
1508 return new NVcltQFp<float>(machInst, vd, vm);
1509 } else {
1510 return new NVcltDFp<float>(machInst, vd, vm);
1511 }
1512 } else {
1513 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1514 q, size, machInst, vd, vm);
1515 }
1516 case 0x6:
1517 if (bits(machInst, 10)) {
1518 if (q)
1519 return new NVabsQFp<float>(machInst, vd, vm);
1520 else
1521 return new NVabsDFp<float>(machInst, vd, vm);
1522 } else {
1523 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1524 q, size, machInst, vd, vm);
1525 }
1526 case 0x7:
1527 if (bits(machInst, 10)) {
1528 if (q)
1529 return new NVnegQFp<float>(machInst, vd, vm);
1530 else
1531 return new NVnegDFp<float>(machInst, vd, vm);
1532 } else {
1533 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1534 q, size, machInst, vd, vm);
1535 }
1536 }
1537 case 0x2:
1538 switch (bits(b, 4, 1)) {
1539 case 0x0:
1540 if (q)
1541 return new NVswpQ<uint64_t>(machInst, vd, vm);
1542 else
1543 return new NVswpD<uint64_t>(machInst, vd, vm);
1544 case 0x1:
580 }
581 } else {
582 if (u) {
583 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
584 q, size, machInst, vd, vn, vm);
585 } else {
586 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
587 q, size, machInst, vd, vn, vm);
588 }
589 }
590 case 0xc:
591 return new Unknown(machInst);
592 case 0xd:
593 if (b) {
594 if (u) {
595 if (bits(c, 1) == 0) {
596 if (q) {
597 return new NVmulQFp<float>(machInst, vd, vn, vm);
598 } else {
599 return new NVmulDFp<float>(machInst, vd, vn, vm);
600 }
601 } else {
602 return new Unknown(machInst);
603 }
604 } else {
605 if (bits(c, 1) == 0) {
606 if (q) {
607 return new NVmlaQFp<float>(machInst, vd, vn, vm);
608 } else {
609 return new NVmlaDFp<float>(machInst, vd, vn, vm);
610 }
611 } else {
612 if (q) {
613 return new NVmlsQFp<float>(machInst, vd, vn, vm);
614 } else {
615 return new NVmlsDFp<float>(machInst, vd, vn, vm);
616 }
617 }
618 }
619 } else {
620 if (u) {
621 if (bits(c, 1) == 0) {
622 if (q) {
623 return new VpaddQFp<float>(machInst, vd, vn, vm);
624 } else {
625 return new VpaddDFp<float>(machInst, vd, vn, vm);
626 }
627 } else {
628 if (q) {
629 return new VabdQFp<float>(machInst, vd, vn, vm);
630 } else {
631 return new VabdDFp<float>(machInst, vd, vn, vm);
632 }
633 }
634 } else {
635 if (bits(c, 1) == 0) {
636 if (q) {
637 return new VaddQFp<float>(machInst, vd, vn, vm);
638 } else {
639 return new VaddDFp<float>(machInst, vd, vn, vm);
640 }
641 } else {
642 if (q) {
643 return new VsubQFp<float>(machInst, vd, vn, vm);
644 } else {
645 return new VsubDFp<float>(machInst, vd, vn, vm);
646 }
647 }
648 }
649 }
650 case 0xe:
651 if (b) {
652 if (u) {
653 if (bits(c, 1) == 0) {
654 if (q) {
655 return new VacgeQFp<float>(machInst, vd, vn, vm);
656 } else {
657 return new VacgeDFp<float>(machInst, vd, vn, vm);
658 }
659 } else {
660 if (q) {
661 return new VacgtQFp<float>(machInst, vd, vn, vm);
662 } else {
663 return new VacgtDFp<float>(machInst, vd, vn, vm);
664 }
665 }
666 } else {
667 return new Unknown(machInst);
668 }
669 } else {
670 if (u) {
671 if (bits(c, 1) == 0) {
672 if (q) {
673 return new VcgeQFp<float>(machInst, vd, vn, vm);
674 } else {
675 return new VcgeDFp<float>(machInst, vd, vn, vm);
676 }
677 } else {
678 if (q) {
679 return new VcgtQFp<float>(machInst, vd, vn, vm);
680 } else {
681 return new VcgtDFp<float>(machInst, vd, vn, vm);
682 }
683 }
684 } else {
685 if (bits(c, 1) == 0) {
686 if (q) {
687 return new VceqQFp<float>(machInst, vd, vn, vm);
688 } else {
689 return new VceqDFp<float>(machInst, vd, vn, vm);
690 }
691 } else {
692 return new Unknown(machInst);
693 }
694 }
695 }
696 case 0xf:
697 if (b) {
698 if (u) {
699 return new Unknown(machInst);
700 } else {
701 if (bits(c, 1) == 0) {
702 if (q) {
703 return new VrecpsQFp<float>(machInst, vd, vn, vm);
704 } else {
705 return new VrecpsDFp<float>(machInst, vd, vn, vm);
706 }
707 } else {
708 if (q) {
709 return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
710 } else {
711 return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
712 }
713 }
714 }
715 } else {
716 if (u) {
717 if (bits(c, 1) == 0) {
718 if (q) {
719 return new VpmaxQFp<float>(machInst, vd, vn, vm);
720 } else {
721 return new VpmaxDFp<float>(machInst, vd, vn, vm);
722 }
723 } else {
724 if (q) {
725 return new VpminQFp<float>(machInst, vd, vn, vm);
726 } else {
727 return new VpminDFp<float>(machInst, vd, vn, vm);
728 }
729 }
730 } else {
731 if (bits(c, 1) == 0) {
732 if (q) {
733 return new VmaxQFp<float>(machInst, vd, vn, vm);
734 } else {
735 return new VmaxDFp<float>(machInst, vd, vn, vm);
736 }
737 } else {
738 if (q) {
739 return new VminQFp<float>(machInst, vd, vn, vm);
740 } else {
741 return new VminDFp<float>(machInst, vd, vn, vm);
742 }
743 }
744 }
745 }
746 }
747 return new Unknown(machInst);
748 }
749
750 static StaticInstPtr
751 decodeNeonOneRegModImm(ExtMachInst machInst)
752 {
753 const IntRegIndex vd =
754 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
755 (bits(machInst, 22) << 4)));
756 const bool q = bits(machInst, 6);
757 const bool op = bits(machInst, 5);
758 const uint8_t cmode = bits(machInst, 11, 8);
759 const uint8_t imm = ((THUMB ? bits(machInst, 28) :
760 bits(machInst, 24)) << 7) |
761 (bits(machInst, 18, 16) << 4) |
762 (bits(machInst, 3, 0) << 0);
763
764 // Check for invalid immediate encodings and return an unknown op
765 // if it happens
766 bool immValid = true;
767 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
768 if (!immValid) {
769 return new Unknown(machInst);
770 }
771
772 if (op) {
773 if (bits(cmode, 3) == 0) {
774 if (bits(cmode, 0) == 0) {
775 if (q)
776 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
777 else
778 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
779 } else {
780 if (q)
781 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
782 else
783 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
784 }
785 } else {
786 if (bits(cmode, 2) == 1) {
787 switch (bits(cmode, 1, 0)) {
788 case 0:
789 case 1:
790 if (q)
791 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
792 else
793 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
794 case 2:
795 if (q)
796 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
797 else
798 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
799 case 3:
800 if (q)
801 return new Unknown(machInst);
802 else
803 return new Unknown(machInst);
804 }
805 } else {
806 if (bits(cmode, 0) == 0) {
807 if (q)
808 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
809 else
810 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
811 } else {
812 if (q)
813 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
814 else
815 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
816 }
817 }
818 }
819 } else {
820 if (bits(cmode, 3) == 0) {
821 if (bits(cmode, 0) == 0) {
822 if (q)
823 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
824 else
825 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
826 } else {
827 if (q)
828 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
829 else
830 return new NVorriD<uint64_t>(machInst, vd, bigImm);
831 }
832 } else {
833 if (bits(cmode, 2) == 1) {
834 if (q)
835 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
836 else
837 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
838 } else {
839 if (bits(cmode, 0) == 0) {
840 if (q)
841 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
842 else
843 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
844 } else {
845 if (q)
846 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
847 else
848 return new NVorriD<uint64_t>(machInst, vd, bigImm);
849 }
850 }
851 }
852 }
853 return new Unknown(machInst);
854 }
855
856 static StaticInstPtr
857 decodeNeonTwoRegAndShift(ExtMachInst machInst)
858 {
859 const uint32_t a = bits(machInst, 11, 8);
860 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
861 const bool b = bits(machInst, 6);
862 const bool l = bits(machInst, 7);
863 const IntRegIndex vd =
864 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
865 (bits(machInst, 22) << 4)));
866 const IntRegIndex vm =
867 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
868 (bits(machInst, 5) << 4)));
869 unsigned imm6 = bits(machInst, 21, 16);
870 unsigned imm = ((l ? 1 : 0) << 6) | imm6;
871 unsigned size = 3;
872 unsigned lShiftAmt = 0;
873 unsigned bitSel;
874 for (bitSel = 1 << 6; true; bitSel >>= 1) {
875 if (bitSel & imm)
876 break;
877 else if (!size)
878 return new Unknown(machInst);
879 size--;
880 }
881 lShiftAmt = imm6 & ~bitSel;
882 unsigned rShiftAmt = 0;
883 if (a != 0xe && a != 0xf) {
884 if (size > 2)
885 rShiftAmt = 64 - imm6;
886 else
887 rShiftAmt = 2 * (8 << size) - imm6;
888 }
889
890 switch (a) {
891 case 0x0:
892 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
893 b, u, size, machInst, vd, vm, rShiftAmt);
894 case 0x1:
895 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
896 b, u, size, machInst, vd, vm, rShiftAmt);
897 case 0x2:
898 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
899 b, u, size, machInst, vd, vm, rShiftAmt);
900 case 0x3:
901 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
902 b, u, size, machInst, vd, vm, rShiftAmt);
903 case 0x4:
904 if (u) {
905 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
906 b, size, machInst, vd, vm, rShiftAmt);
907 } else {
908 return new Unknown(machInst);
909 }
910 case 0x5:
911 if (u) {
912 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
913 b, size, machInst, vd, vm, lShiftAmt);
914 } else {
915 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
916 b, size, machInst, vd, vm, lShiftAmt);
917 }
918 case 0x6:
919 case 0x7:
920 if (u) {
921 if (a == 0x6) {
922 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
923 b, size, machInst, vd, vm, lShiftAmt);
924 } else {
925 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
926 b, size, machInst, vd, vm, lShiftAmt);
927 }
928 } else {
929 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
930 b, size, machInst, vd, vm, lShiftAmt);
931 }
932 case 0x8:
933 if (l) {
934 return new Unknown(machInst);
935 } else if (u) {
936 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
937 b, size, machInst, vd, vm, rShiftAmt);
938 } else {
939 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
940 b, size, machInst, vd, vm, rShiftAmt);
941 }
942 case 0x9:
943 if (l) {
944 return new Unknown(machInst);
945 } else if (u) {
946 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
947 b, size, machInst, vd, vm, rShiftAmt);
948 } else {
949 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
950 b, size, machInst, vd, vm, rShiftAmt);
951 }
952 case 0xa:
953 if (l || b) {
954 return new Unknown(machInst);
955 } else {
956 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
957 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
958 }
959 case 0xe:
960 if (l) {
961 return new Unknown(machInst);
962 } else {
963 if (bits(imm6, 5) == 0)
964 return new Unknown(machInst);
965 if (u) {
966 if (b) {
967 return new NVcvtu2fpQ<float>(
968 machInst, vd, vm, 64 - imm6);
969 } else {
970 return new NVcvtu2fpD<float>(
971 machInst, vd, vm, 64 - imm6);
972 }
973 } else {
974 if (b) {
975 return new NVcvts2fpQ<float>(
976 machInst, vd, vm, 64 - imm6);
977 } else {
978 return new NVcvts2fpD<float>(
979 machInst, vd, vm, 64 - imm6);
980 }
981 }
982 }
983 case 0xf:
984 if (l) {
985 return new Unknown(machInst);
986 } else {
987 if (bits(imm6, 5) == 0)
988 return new Unknown(machInst);
989 if (u) {
990 if (b) {
991 return new NVcvt2ufxQ<float>(
992 machInst, vd, vm, 64 - imm6);
993 } else {
994 return new NVcvt2ufxD<float>(
995 machInst, vd, vm, 64 - imm6);
996 }
997 } else {
998 if (b) {
999 return new NVcvt2sfxQ<float>(
1000 machInst, vd, vm, 64 - imm6);
1001 } else {
1002 return new NVcvt2sfxD<float>(
1003 machInst, vd, vm, 64 - imm6);
1004 }
1005 }
1006 }
1007 }
1008 return new Unknown(machInst);
1009 }
1010
1011 static StaticInstPtr
1012 decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1013 {
1014 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1015 const uint32_t a = bits(machInst, 11, 8);
1016 const IntRegIndex vd =
1017 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1018 (bits(machInst, 22) << 4)));
1019 const IntRegIndex vn =
1020 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1021 (bits(machInst, 7) << 4)));
1022 const IntRegIndex vm =
1023 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1024 (bits(machInst, 5) << 4)));
1025 const unsigned size = bits(machInst, 21, 20);
1026 switch (a) {
1027 case 0x0:
1028 return decodeNeonUSThreeUSReg<Vaddl>(
1029 u, size, machInst, vd, vn, vm);
1030 case 0x1:
1031 return decodeNeonUSThreeUSReg<Vaddw>(
1032 u, size, machInst, vd, vn, vm);
1033 case 0x2:
1034 return decodeNeonUSThreeUSReg<Vsubl>(
1035 u, size, machInst, vd, vn, vm);
1036 case 0x3:
1037 return decodeNeonUSThreeUSReg<Vsubw>(
1038 u, size, machInst, vd, vn, vm);
1039 case 0x4:
1040 if (u) {
1041 return decodeNeonUThreeUSReg<Vraddhn>(
1042 size, machInst, vd, vn, vm);
1043 } else {
1044 return decodeNeonUThreeUSReg<Vaddhn>(
1045 size, machInst, vd, vn, vm);
1046 }
1047 case 0x5:
1048 return decodeNeonUSThreeUSReg<Vabal>(
1049 u, size, machInst, vd, vn, vm);
1050 case 0x6:
1051 if (u) {
1052 return decodeNeonUThreeUSReg<Vrsubhn>(
1053 size, machInst, vd, vn, vm);
1054 } else {
1055 return decodeNeonUThreeUSReg<Vsubhn>(
1056 size, machInst, vd, vn, vm);
1057 }
1058 case 0x7:
1059 if (bits(machInst, 23)) {
1060 return decodeNeonUSThreeUSReg<Vabdl>(
1061 u, size, machInst, vd, vn, vm);
1062 } else {
1063 return decodeNeonUSThreeReg<VabdD, VabdQ>(
1064 bits(machInst, 6), u, size, machInst, vd, vn, vm);
1065 }
1066 case 0x8:
1067 return decodeNeonUSThreeUSReg<Vmlal>(
1068 u, size, machInst, vd, vn, vm);
1069 case 0xa:
1070 return decodeNeonUSThreeUSReg<Vmlsl>(
1071 u, size, machInst, vd, vn, vm);
1072 case 0x9:
1073 if (u) {
1074 return new Unknown(machInst);
1075 } else {
1076 return decodeNeonSThreeUSReg<Vqdmlal>(
1077 size, machInst, vd, vn, vm);
1078 }
1079 case 0xb:
1080 if (u) {
1081 return new Unknown(machInst);
1082 } else {
1083 return decodeNeonSThreeUSReg<Vqdmlsl>(
1084 size, machInst, vd, vn, vm);
1085 }
1086 case 0xc:
1087 return decodeNeonUSThreeUSReg<Vmull>(
1088 u, size, machInst, vd, vn, vm);
1089 case 0xd:
1090 if (u) {
1091 return new Unknown(machInst);
1092 } else {
1093 return decodeNeonSThreeUSReg<Vqdmull>(
1094 size, machInst, vd, vn, vm);
1095 }
1096 case 0xe:
1097 return decodeNeonUThreeUSReg<Vmullp>(
1098 size, machInst, vd, vn, vm);
1099 }
1100 return new Unknown(machInst);
1101 }
1102
1103 static StaticInstPtr
1104 decodeNeonTwoRegScalar(ExtMachInst machInst)
1105 {
1106 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1107 const uint32_t a = bits(machInst, 11, 8);
1108 const unsigned size = bits(machInst, 21, 20);
1109 const IntRegIndex vd =
1110 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1111 (bits(machInst, 22) << 4)));
1112 const IntRegIndex vn =
1113 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1114 (bits(machInst, 7) << 4)));
1115 const IntRegIndex vm = (size == 2) ?
1116 (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1117 (IntRegIndex)(2 * bits(machInst, 2, 0));
1118 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1119 (bits(machInst, 3) | (bits(machInst, 5) << 1));
1120 switch (a) {
1121 case 0x0:
1122 if (u) {
1123 switch (size) {
1124 case 1:
1125 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1126 case 2:
1127 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1128 default:
1129 return new Unknown(machInst);
1130 }
1131 } else {
1132 switch (size) {
1133 case 1:
1134 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1135 case 2:
1136 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1137 default:
1138 return new Unknown(machInst);
1139 }
1140 }
1141 case 0x1:
1142 if (u)
1143 return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1144 else
1145 return new VmlasDFp<float>(machInst, vd, vn, vm, index);
1146 case 0x4:
1147 if (u) {
1148 switch (size) {
1149 case 1:
1150 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1151 case 2:
1152 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1153 default:
1154 return new Unknown(machInst);
1155 }
1156 } else {
1157 switch (size) {
1158 case 1:
1159 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1160 case 2:
1161 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1162 default:
1163 return new Unknown(machInst);
1164 }
1165 }
1166 case 0x5:
1167 if (u)
1168 return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1169 else
1170 return new VmlssDFp<float>(machInst, vd, vn, vm, index);
1171 case 0x2:
1172 if (u) {
1173 switch (size) {
1174 case 1:
1175 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1176 case 2:
1177 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1178 default:
1179 return new Unknown(machInst);
1180 }
1181 } else {
1182 switch (size) {
1183 case 1:
1184 return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1185 case 2:
1186 return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1187 default:
1188 return new Unknown(machInst);
1189 }
1190 }
1191 case 0x6:
1192 if (u) {
1193 switch (size) {
1194 case 1:
1195 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1196 case 2:
1197 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1198 default:
1199 return new Unknown(machInst);
1200 }
1201 } else {
1202 switch (size) {
1203 case 1:
1204 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1205 case 2:
1206 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1207 default:
1208 return new Unknown(machInst);
1209 }
1210 }
1211 case 0x3:
1212 if (u) {
1213 return new Unknown(machInst);
1214 } else {
1215 switch (size) {
1216 case 1:
1217 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1218 case 2:
1219 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1220 default:
1221 return new Unknown(machInst);
1222 }
1223 }
1224 case 0x7:
1225 if (u) {
1226 return new Unknown(machInst);
1227 } else {
1228 switch (size) {
1229 case 1:
1230 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1231 case 2:
1232 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1233 default:
1234 return new Unknown(machInst);
1235 }
1236 }
1237 case 0x8:
1238 if (u) {
1239 switch (size) {
1240 case 1:
1241 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1242 case 2:
1243 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1244 default:
1245 return new Unknown(machInst);
1246 }
1247 } else {
1248 switch (size) {
1249 case 1:
1250 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1251 case 2:
1252 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1253 default:
1254 return new Unknown(machInst);
1255 }
1256 }
1257 case 0x9:
1258 if (u)
1259 return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1260 else
1261 return new VmulsDFp<float>(machInst, vd, vn, vm, index);
1262 case 0xa:
1263 if (u) {
1264 switch (size) {
1265 case 1:
1266 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1267 case 2:
1268 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1269 default:
1270 return new Unknown(machInst);
1271 }
1272 } else {
1273 switch (size) {
1274 case 1:
1275 return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1276 case 2:
1277 return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1278 default:
1279 return new Unknown(machInst);
1280 }
1281 }
1282 case 0xb:
1283 if (u) {
1284 return new Unknown(machInst);
1285 } else {
1286 if (u) {
1287 switch (size) {
1288 case 1:
1289 return new Vqdmulls<uint16_t>(
1290 machInst, vd, vn, vm, index);
1291 case 2:
1292 return new Vqdmulls<uint32_t>(
1293 machInst, vd, vn, vm, index);
1294 default:
1295 return new Unknown(machInst);
1296 }
1297 } else {
1298 switch (size) {
1299 case 1:
1300 return new Vqdmulls<int16_t>(
1301 machInst, vd, vn, vm, index);
1302 case 2:
1303 return new Vqdmulls<int32_t>(
1304 machInst, vd, vn, vm, index);
1305 default:
1306 return new Unknown(machInst);
1307 }
1308 }
1309 }
1310 case 0xc:
1311 if (u) {
1312 switch (size) {
1313 case 1:
1314 return new VqdmulhsQ<int16_t>(
1315 machInst, vd, vn, vm, index);
1316 case 2:
1317 return new VqdmulhsQ<int32_t>(
1318 machInst, vd, vn, vm, index);
1319 default:
1320 return new Unknown(machInst);
1321 }
1322 } else {
1323 switch (size) {
1324 case 1:
1325 return new VqdmulhsD<int16_t>(
1326 machInst, vd, vn, vm, index);
1327 case 2:
1328 return new VqdmulhsD<int32_t>(
1329 machInst, vd, vn, vm, index);
1330 default:
1331 return new Unknown(machInst);
1332 }
1333 }
1334 case 0xd:
1335 if (u) {
1336 switch (size) {
1337 case 1:
1338 return new VqrdmulhsQ<int16_t>(
1339 machInst, vd, vn, vm, index);
1340 case 2:
1341 return new VqrdmulhsQ<int32_t>(
1342 machInst, vd, vn, vm, index);
1343 default:
1344 return new Unknown(machInst);
1345 }
1346 } else {
1347 switch (size) {
1348 case 1:
1349 return new VqrdmulhsD<int16_t>(
1350 machInst, vd, vn, vm, index);
1351 case 2:
1352 return new VqrdmulhsD<int32_t>(
1353 machInst, vd, vn, vm, index);
1354 default:
1355 return new Unknown(machInst);
1356 }
1357 }
1358 }
1359 return new Unknown(machInst);
1360 }
1361
1362 static StaticInstPtr
1363 decodeNeonTwoRegMisc(ExtMachInst machInst)
1364 {
1365 const uint32_t a = bits(machInst, 17, 16);
1366 const uint32_t b = bits(machInst, 10, 6);
1367 const bool q = bits(machInst, 6);
1368 const IntRegIndex vd =
1369 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1370 (bits(machInst, 22) << 4)));
1371 const IntRegIndex vm =
1372 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1373 (bits(machInst, 5) << 4)));
1374 const unsigned size = bits(machInst, 19, 18);
1375 switch (a) {
1376 case 0x0:
1377 switch (bits(b, 4, 1)) {
1378 case 0x0:
1379 switch (size) {
1380 case 0:
1381 if (q) {
1382 return new NVrev64Q<uint8_t>(machInst, vd, vm);
1383 } else {
1384 return new NVrev64D<uint8_t>(machInst, vd, vm);
1385 }
1386 case 1:
1387 if (q) {
1388 return new NVrev64Q<uint16_t>(machInst, vd, vm);
1389 } else {
1390 return new NVrev64D<uint16_t>(machInst, vd, vm);
1391 }
1392 case 2:
1393 if (q) {
1394 return new NVrev64Q<uint32_t>(machInst, vd, vm);
1395 } else {
1396 return new NVrev64D<uint32_t>(machInst, vd, vm);
1397 }
1398 default:
1399 return new Unknown(machInst);
1400 }
1401 case 0x1:
1402 switch (size) {
1403 case 0:
1404 if (q) {
1405 return new NVrev32Q<uint8_t>(machInst, vd, vm);
1406 } else {
1407 return new NVrev32D<uint8_t>(machInst, vd, vm);
1408 }
1409 case 1:
1410 if (q) {
1411 return new NVrev32Q<uint16_t>(machInst, vd, vm);
1412 } else {
1413 return new NVrev32D<uint16_t>(machInst, vd, vm);
1414 }
1415 default:
1416 return new Unknown(machInst);
1417 }
1418 case 0x2:
1419 if (size != 0) {
1420 return new Unknown(machInst);
1421 } else if (q) {
1422 return new NVrev16Q<uint8_t>(machInst, vd, vm);
1423 } else {
1424 return new NVrev16D<uint8_t>(machInst, vd, vm);
1425 }
1426 case 0x4:
1427 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1428 q, size, machInst, vd, vm);
1429 case 0x5:
1430 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1431 q, size, machInst, vd, vm);
1432 case 0x8:
1433 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1434 q, size, machInst, vd, vm);
1435 case 0x9:
1436 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1437 q, size, machInst, vd, vm);
1438 case 0xa:
1439 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1440 q, size, machInst, vd, vm);
1441 case 0xb:
1442 if (q)
1443 return new NVmvnQ<uint64_t>(machInst, vd, vm);
1444 else
1445 return new NVmvnD<uint64_t>(machInst, vd, vm);
1446 case 0xc:
1447 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1448 q, size, machInst, vd, vm);
1449 case 0xd:
1450 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1451 q, size, machInst, vd, vm);
1452 case 0xe:
1453 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1454 q, size, machInst, vd, vm);
1455 case 0xf:
1456 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1457 q, size, machInst, vd, vm);
1458 default:
1459 return new Unknown(machInst);
1460 }
1461 case 0x1:
1462 switch (bits(b, 3, 1)) {
1463 case 0x0:
1464 if (bits(b, 4)) {
1465 if (q) {
1466 return new NVcgtQFp<float>(machInst, vd, vm);
1467 } else {
1468 return new NVcgtDFp<float>(machInst, vd, vm);
1469 }
1470 } else {
1471 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1472 q, size, machInst, vd, vm);
1473 }
1474 case 0x1:
1475 if (bits(b, 4)) {
1476 if (q) {
1477 return new NVcgeQFp<float>(machInst, vd, vm);
1478 } else {
1479 return new NVcgeDFp<float>(machInst, vd, vm);
1480 }
1481 } else {
1482 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1483 q, size, machInst, vd, vm);
1484 }
1485 case 0x2:
1486 if (bits(b, 4)) {
1487 if (q) {
1488 return new NVceqQFp<float>(machInst, vd, vm);
1489 } else {
1490 return new NVceqDFp<float>(machInst, vd, vm);
1491 }
1492 } else {
1493 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1494 q, size, machInst, vd, vm);
1495 }
1496 case 0x3:
1497 if (bits(b, 4)) {
1498 if (q) {
1499 return new NVcleQFp<float>(machInst, vd, vm);
1500 } else {
1501 return new NVcleDFp<float>(machInst, vd, vm);
1502 }
1503 } else {
1504 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1505 q, size, machInst, vd, vm);
1506 }
1507 case 0x4:
1508 if (bits(b, 4)) {
1509 if (q) {
1510 return new NVcltQFp<float>(machInst, vd, vm);
1511 } else {
1512 return new NVcltDFp<float>(machInst, vd, vm);
1513 }
1514 } else {
1515 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1516 q, size, machInst, vd, vm);
1517 }
1518 case 0x6:
1519 if (bits(machInst, 10)) {
1520 if (q)
1521 return new NVabsQFp<float>(machInst, vd, vm);
1522 else
1523 return new NVabsDFp<float>(machInst, vd, vm);
1524 } else {
1525 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1526 q, size, machInst, vd, vm);
1527 }
1528 case 0x7:
1529 if (bits(machInst, 10)) {
1530 if (q)
1531 return new NVnegQFp<float>(machInst, vd, vm);
1532 else
1533 return new NVnegDFp<float>(machInst, vd, vm);
1534 } else {
1535 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1536 q, size, machInst, vd, vm);
1537 }
1538 }
1539 case 0x2:
1540 switch (bits(b, 4, 1)) {
1541 case 0x0:
1542 if (q)
1543 return new NVswpQ<uint64_t>(machInst, vd, vm);
1544 else
1545 return new NVswpD<uint64_t>(machInst, vd, vm);
1546 case 0x1:
1545 return decodeNeonUTwoMiscReg(
1547 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>(
1546 q, size, machInst, vd, vm);
1547 case 0x2:
1548 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1549 q, size, machInst, vd, vm);
1550 case 0x3:
1551 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1552 q, size, machInst, vd, vm);
1553 case 0x4:
1554 if (b == 0x8) {
1555 return decodeNeonUTwoMiscUSReg<NVmovn>(
1556 size, machInst, vd, vm);
1557 } else {
1558 return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1559 size, machInst, vd, vm);
1560 }
1561 case 0x5:
1562 if (q) {
1563 return decodeNeonUTwoMiscUSReg<NVqmovun>(
1564 size, machInst, vd, vm);
1565 } else {
1566 return decodeNeonSTwoMiscUSReg<NVqmovn>(
1567 size, machInst, vd, vm);
1568 }
1569 case 0x6:
1570 if (b == 0xc) {
1571 const IntRegIndex vd =
1572 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1573 (bits(machInst, 22) << 4)));
1574 const IntRegIndex vm =
1575 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1576 (bits(machInst, 5) << 4)));
1577 unsigned size = bits(machInst, 19, 18);
1578 return decodeNeonSTwoShiftUSReg<NVshll>(
1579 size, machInst, vd, vm, 8 << size);
1580 } else {
1581 return new Unknown(machInst);
1582 }
1583 case 0xc:
1584 case 0xe:
1585 if (b == 0x18) {
1586 if (size != 1 || (vm % 2))
1587 return new Unknown(machInst);
1588 return new NVcvts2h<uint16_t>(machInst, vd, vm);
1589 } else if (b == 0x1c) {
1590 if (size != 1 || (vd % 2))
1591 return new Unknown(machInst);
1592 return new NVcvth2s<uint16_t>(machInst, vd, vm);
1593 } else {
1594 return new Unknown(machInst);
1595 }
1596 default:
1597 return new Unknown(machInst);
1598 }
1599 case 0x3:
1600 if (bits(b, 4, 3) == 0x3) {
1601 if ((q && (vd % 2 || vm % 2)) || size != 2) {
1602 return new Unknown(machInst);
1603 } else {
1604 if (bits(b, 2)) {
1605 if (bits(b, 1)) {
1606 if (q) {
1607 return new NVcvt2ufxQ<float>(
1608 machInst, vd, vm, 0);
1609 } else {
1610 return new NVcvt2ufxD<float>(
1611 machInst, vd, vm, 0);
1612 }
1613 } else {
1614 if (q) {
1615 return new NVcvt2sfxQ<float>(
1616 machInst, vd, vm, 0);
1617 } else {
1618 return new NVcvt2sfxD<float>(
1619 machInst, vd, vm, 0);
1620 }
1621 }
1622 } else {
1623 if (bits(b, 1)) {
1624 if (q) {
1625 return new NVcvtu2fpQ<float>(
1626 machInst, vd, vm, 0);
1627 } else {
1628 return new NVcvtu2fpD<float>(
1629 machInst, vd, vm, 0);
1630 }
1631 } else {
1632 if (q) {
1633 return new NVcvts2fpQ<float>(
1634 machInst, vd, vm, 0);
1635 } else {
1636 return new NVcvts2fpD<float>(
1637 machInst, vd, vm, 0);
1638 }
1639 }
1640 }
1641 }
1642 } else if ((b & 0x1a) == 0x10) {
1643 if (bits(b, 2)) {
1644 if (q) {
1645 return new NVrecpeQFp<float>(machInst, vd, vm);
1646 } else {
1647 return new NVrecpeDFp<float>(machInst, vd, vm);
1648 }
1649 } else {
1650 if (q) {
1651 return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1652 } else {
1653 return new NVrecpeD<uint32_t>(machInst, vd, vm);
1654 }
1655 }
1656 } else if ((b & 0x1a) == 0x12) {
1657 if (bits(b, 2)) {
1658 if (q) {
1659 return new NVrsqrteQFp<float>(machInst, vd, vm);
1660 } else {
1661 return new NVrsqrteDFp<float>(machInst, vd, vm);
1662 }
1663 } else {
1664 if (q) {
1665 return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1666 } else {
1667 return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1668 }
1669 }
1670 } else {
1671 return new Unknown(machInst);
1672 }
1673 }
1674 return new Unknown(machInst);
1675 }
1676
1677 StaticInstPtr
1678 decodeNeonData(ExtMachInst machInst)
1679 {
1680 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1681 const uint32_t a = bits(machInst, 23, 19);
1682 const uint32_t b = bits(machInst, 11, 8);
1683 const uint32_t c = bits(machInst, 7, 4);
1684 if (bits(a, 4) == 0) {
1685 return decodeNeonThreeRegistersSameLength(machInst);
1686 } else if ((c & 0x9) == 1) {
1687 if ((a & 0x7) == 0) {
1688 return decodeNeonOneRegModImm(machInst);
1689 } else {
1690 return decodeNeonTwoRegAndShift(machInst);
1691 }
1692 } else if ((c & 0x9) == 9) {
1693 return decodeNeonTwoRegAndShift(machInst);
1694 } else if (bits(a, 2, 1) != 0x3) {
1695 if ((c & 0x5) == 0) {
1696 return decodeNeonThreeRegDiffLengths(machInst);
1697 } else if ((c & 0x5) == 4) {
1698 return decodeNeonTwoRegScalar(machInst);
1699 }
1700 } else if ((a & 0x16) == 0x16) {
1701 const IntRegIndex vd =
1702 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1703 (bits(machInst, 22) << 4)));
1704 const IntRegIndex vn =
1705 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1706 (bits(machInst, 7) << 4)));
1707 const IntRegIndex vm =
1708 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1709 (bits(machInst, 5) << 4)));
1710 if (!u) {
1711 if (bits(c, 0) == 0) {
1712 unsigned imm4 = bits(machInst, 11, 8);
1713 bool q = bits(machInst, 6);
1714 if (imm4 >= 16 && !q)
1715 return new Unknown(machInst);
1716 if (q) {
1717 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1718 } else {
1719 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1720 }
1721 }
1722 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1723 return decodeNeonTwoRegMisc(machInst);
1724 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1725 unsigned length = bits(machInst, 9, 8) + 1;
1726 if ((uint32_t)vn / 2 + length > 32)
1727 return new Unknown(machInst);
1728 if (bits(machInst, 6) == 0) {
1729 switch (length) {
1730 case 1:
1731 return new NVtbl1(machInst, vd, vn, vm);
1732 case 2:
1733 return new NVtbl2(machInst, vd, vn, vm);
1734 case 3:
1735 return new NVtbl3(machInst, vd, vn, vm);
1736 case 4:
1737 return new NVtbl4(machInst, vd, vn, vm);
1738 }
1739 } else {
1740 switch (length) {
1741 case 1:
1742 return new NVtbx1(machInst, vd, vn, vm);
1743 case 2:
1744 return new NVtbx2(machInst, vd, vn, vm);
1745 case 3:
1746 return new NVtbx3(machInst, vd, vn, vm);
1747 case 4:
1748 return new NVtbx4(machInst, vd, vn, vm);
1749 }
1750 }
1751 } else if (b == 0xc && (c & 0x9) == 0) {
1752 unsigned imm4 = bits(machInst, 19, 16);
1753 if (bits(imm4, 2, 0) == 0)
1754 return new Unknown(machInst);
1755 unsigned size = 0;
1756 while ((imm4 & 0x1) == 0) {
1757 size++;
1758 imm4 >>= 1;
1759 }
1760 unsigned index = imm4 >> 1;
1761 const bool q = bits(machInst, 6);
1762 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1763 q, size, machInst, vd, vm, index);
1764 }
1765 }
1766 return new Unknown(machInst);
1767 }
1768 '''
1769}};
1770
1771def format ThumbNeonMem() {{
1772 decode_block = '''
1773 return decodeNeonMem(machInst);
1774 '''
1775}};
1776
1777def format ThumbNeonData() {{
1778 decode_block = '''
1779 return decodeNeonData(machInst);
1780 '''
1781}};
1782
1783let {{
1784 header_output = '''
1785 StaticInstPtr
1786 decodeExtensionRegLoadStore(ExtMachInst machInst);
1787 '''
1788 decoder_output = '''
1789 StaticInstPtr
1790 decodeExtensionRegLoadStore(ExtMachInst machInst)
1791 {
1792 const uint32_t opcode = bits(machInst, 24, 20);
1793 const uint32_t offset = bits(machInst, 7, 0);
1794 const bool single = (bits(machInst, 8) == 0);
1795 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1796 RegIndex vd;
1797 if (single) {
1798 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1799 bits(machInst, 22));
1800 } else {
1801 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1802 (bits(machInst, 22) << 5));
1803 }
1804 switch (bits(opcode, 4, 3)) {
1805 case 0x0:
1806 if (bits(opcode, 4, 1) == 0x2 &&
1807 !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1808 !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1809 if ((bits(machInst, 7, 4) & 0xd) != 1) {
1810 break;
1811 }
1812 const IntRegIndex rt =
1813 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1814 const IntRegIndex rt2 =
1815 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1816 const bool op = bits(machInst, 20);
1817 uint32_t vm;
1818 if (single) {
1819 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1820 } else {
1821 vm = (bits(machInst, 3, 0) << 1) |
1822 (bits(machInst, 5) << 5);
1823 }
1824 if (op) {
1825 return new Vmov2Core2Reg(machInst, rt, rt2,
1826 (IntRegIndex)vm);
1827 } else {
1828 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1829 rt, rt2);
1830 }
1831 }
1832 break;
1833 case 0x1:
1834 {
1835 if (offset == 0 || vd + offset/2 > NumFloatArchRegs) {
1836 break;
1837 }
1838 switch (bits(opcode, 1, 0)) {
1839 case 0x0:
1840 return new VLdmStm(machInst, rn, vd, single,
1841 true, false, false, offset);
1842 case 0x1:
1843 return new VLdmStm(machInst, rn, vd, single,
1844 true, false, true, offset);
1845 case 0x2:
1846 return new VLdmStm(machInst, rn, vd, single,
1847 true, true, false, offset);
1848 case 0x3:
1849 // If rn == sp, then this is called vpop.
1850 return new VLdmStm(machInst, rn, vd, single,
1851 true, true, true, offset);
1852 }
1853 }
1854 case 0x2:
1855 if (bits(opcode, 1, 0) == 0x2) {
1856 // If rn == sp, then this is called vpush.
1857 return new VLdmStm(machInst, rn, vd, single,
1858 false, true, false, offset);
1859 } else if (bits(opcode, 1, 0) == 0x3) {
1860 return new VLdmStm(machInst, rn, vd, single,
1861 false, true, true, offset);
1862 }
1863 // Fall through on purpose
1864 case 0x3:
1865 const bool up = (bits(machInst, 23) == 1);
1866 const uint32_t imm = bits(machInst, 7, 0) << 2;
1867 RegIndex vd;
1868 if (single) {
1869 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1870 (bits(machInst, 22)));
1871 } else {
1872 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1873 (bits(machInst, 22) << 5));
1874 }
1875 if (bits(opcode, 1, 0) == 0x0) {
1876 if (single) {
1877 if (up) {
1878 return new %(vstr_us)s(machInst, vd, rn, up, imm);
1879 } else {
1880 return new %(vstr_s)s(machInst, vd, rn, up, imm);
1881 }
1882 } else {
1883 if (up) {
1884 return new %(vstr_ud)s(machInst, vd, vd + 1,
1885 rn, up, imm);
1886 } else {
1887 return new %(vstr_d)s(machInst, vd, vd + 1,
1888 rn, up, imm);
1889 }
1890 }
1891 } else if (bits(opcode, 1, 0) == 0x1) {
1892 if (single) {
1893 if (up) {
1894 return new %(vldr_us)s(machInst, vd, rn, up, imm);
1895 } else {
1896 return new %(vldr_s)s(machInst, vd, rn, up, imm);
1897 }
1898 } else {
1899 if (up) {
1900 return new %(vldr_ud)s(machInst, vd, vd + 1,
1901 rn, up, imm);
1902 } else {
1903 return new %(vldr_d)s(machInst, vd, vd + 1,
1904 rn, up, imm);
1905 }
1906 }
1907 }
1908 }
1909 return new Unknown(machInst);
1910 }
1911 ''' % {
1912 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1913 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1914 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1915 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1916 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1917 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1918 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1919 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1920 }
1921}};
1922
1923def format ExtensionRegLoadStore() {{
1924 decode_block = '''
1925 return decodeExtensionRegLoadStore(machInst);
1926 '''
1927}};
1928
1929let {{
1930 header_output = '''
1931 StaticInstPtr
1932 decodeShortFpTransfer(ExtMachInst machInst);
1933 '''
1934 decoder_output = '''
1935 StaticInstPtr
1936 decodeShortFpTransfer(ExtMachInst machInst)
1937 {
1938 const uint32_t l = bits(machInst, 20);
1939 const uint32_t c = bits(machInst, 8);
1940 const uint32_t a = bits(machInst, 23, 21);
1941 const uint32_t b = bits(machInst, 6, 5);
1942 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1943 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1944 return new Unknown(machInst);
1945 }
1946 if (l == 0 && c == 0) {
1947 if (a == 0) {
1948 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
1949 bits(machInst, 7);
1950 const IntRegIndex rt =
1951 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1952 if (bits(machInst, 20) == 1) {
1953 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1954 } else {
1955 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1956 }
1957 } else if (a == 0x7) {
1958 const IntRegIndex rt =
1959 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1960 uint32_t specReg = bits(machInst, 19, 16);
1961 switch (specReg) {
1962 case 0:
1963 specReg = MISCREG_FPSID;
1964 break;
1965 case 1:
1966 specReg = MISCREG_FPSCR;
1967 break;
1968 case 6:
1969 specReg = MISCREG_MVFR1;
1970 break;
1971 case 7:
1972 specReg = MISCREG_MVFR0;
1973 break;
1974 case 8:
1975 specReg = MISCREG_FPEXC;
1976 break;
1977 default:
1978 return new Unknown(machInst);
1979 }
1980 if (specReg == MISCREG_FPSCR) {
1981 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
1982 } else {
1983 return new Vmsr(machInst, (IntRegIndex)specReg, rt);
1984 }
1985 }
1986 } else if (l == 0 && c == 1) {
1987 if (bits(a, 2) == 0) {
1988 uint32_t vd = (bits(machInst, 7) << 5) |
1989 (bits(machInst, 19, 16) << 1);
1990 // Handle accessing each single precision half of the vector.
1991 vd += bits(machInst, 21);
1992 const IntRegIndex rt =
1993 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1994 if (bits(machInst, 22) == 1) {
1995 return new VmovCoreRegB(machInst, (IntRegIndex)vd,
1996 rt, bits(machInst, 6, 5));
1997 } else if (bits(machInst, 5) == 1) {
1998 return new VmovCoreRegH(machInst, (IntRegIndex)vd,
1999 rt, bits(machInst, 6));
2000 } else if (bits(machInst, 6) == 0) {
2001 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2002 } else {
2003 return new Unknown(machInst);
2004 }
2005 } else if (bits(b, 1) == 0) {
2006 bool q = bits(machInst, 21);
2007 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2008 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2009 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2010 IntRegIndex rt = (IntRegIndex)(uint32_t)
2011 bits(machInst, 15, 12);
2012 if (q) {
2013 switch (be) {
2014 case 0:
2015 return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2016 case 1:
2017 return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2018 case 2:
2019 return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2020 case 3:
2021 return new Unknown(machInst);
2022 }
2023 } else {
2024 switch (be) {
2025 case 0:
2026 return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2027 case 1:
2028 return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2029 case 2:
2030 return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2031 case 3:
2032 return new Unknown(machInst);
2033 }
2034 }
2035 }
2036 } else if (l == 1 && c == 0) {
2037 if (a == 0) {
2038 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2039 bits(machInst, 7);
2040 const IntRegIndex rt =
2041 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2042 if (bits(machInst, 20) == 1) {
2043 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2044 } else {
2045 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2046 }
2047 } else if (a == 7) {
2048 const IntRegIndex rt =
2049 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2050 uint32_t specReg = bits(machInst, 19, 16);
2051 switch (specReg) {
2052 case 0:
2053 specReg = MISCREG_FPSID;
2054 break;
2055 case 1:
2056 specReg = MISCREG_FPSCR;
2057 break;
2058 case 6:
2059 specReg = MISCREG_MVFR1;
2060 break;
2061 case 7:
2062 specReg = MISCREG_MVFR0;
2063 break;
2064 case 8:
2065 specReg = MISCREG_FPEXC;
2066 break;
2067 default:
2068 return new Unknown(machInst);
2069 }
2070 if (rt == 0xf) {
2071 if (specReg == MISCREG_FPSCR) {
2072 return new VmrsApsrFpscr(machInst);
2073 } else {
2074 return new Unknown(machInst);
2075 }
2076 } else if (specReg == MISCREG_FPSCR) {
2077 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2078 } else {
2079 return new Vmrs(machInst, rt, (IntRegIndex)specReg);
2080 }
2081 }
2082 } else {
2083 uint32_t vd = (bits(machInst, 7) << 5) |
2084 (bits(machInst, 19, 16) << 1);
2085 // Handle indexing into each single precision half of the vector.
2086 vd += bits(machInst, 21);
2087 uint32_t index;
2088 const IntRegIndex rt =
2089 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2090 const bool u = (bits(machInst, 23) == 1);
2091 if (bits(machInst, 22) == 1) {
2092 index = bits(machInst, 6, 5);
2093 if (u) {
2094 return new VmovRegCoreUB(machInst, rt,
2095 (IntRegIndex)vd, index);
2096 } else {
2097 return new VmovRegCoreSB(machInst, rt,
2098 (IntRegIndex)vd, index);
2099 }
2100 } else if (bits(machInst, 5) == 1) {
2101 index = bits(machInst, 6);
2102 if (u) {
2103 return new VmovRegCoreUH(machInst, rt,
2104 (IntRegIndex)vd, index);
2105 } else {
2106 return new VmovRegCoreSH(machInst, rt,
2107 (IntRegIndex)vd, index);
2108 }
2109 } else if (bits(machInst, 6) == 0 && !u) {
2110 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2111 } else {
2112 return new Unknown(machInst);
2113 }
2114 }
2115 return new Unknown(machInst);
2116 }
2117 '''
2118}};
2119
2120def format ShortFpTransfer() {{
2121 decode_block = '''
2122 return decodeShortFpTransfer(machInst);
2123 '''
2124}};
2125
2126let {{
2127 header_output = '''
2128 StaticInstPtr
2129 decodeVfpData(ExtMachInst machInst);
2130 '''
2131 decoder_output = '''
2132 StaticInstPtr
2133 decodeVfpData(ExtMachInst machInst)
2134 {
2135 const uint32_t opc1 = bits(machInst, 23, 20);
2136 const uint32_t opc2 = bits(machInst, 19, 16);
2137 const uint32_t opc3 = bits(machInst, 7, 6);
2138 //const uint32_t opc4 = bits(machInst, 3, 0);
2139 const bool single = (bits(machInst, 8) == 0);
2140 // Used to select between vcmp and vcmpe.
2141 const bool e = (bits(machInst, 7) == 1);
2142 IntRegIndex vd;
2143 IntRegIndex vm;
2144 IntRegIndex vn;
2145 if (single) {
2146 vd = (IntRegIndex)(bits(machInst, 22) |
2147 (bits(machInst, 15, 12) << 1));
2148 vm = (IntRegIndex)(bits(machInst, 5) |
2149 (bits(machInst, 3, 0) << 1));
2150 vn = (IntRegIndex)(bits(machInst, 7) |
2151 (bits(machInst, 19, 16) << 1));
2152 } else {
2153 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2154 (bits(machInst, 15, 12) << 1));
2155 vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2156 (bits(machInst, 3, 0) << 1));
2157 vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2158 (bits(machInst, 19, 16) << 1));
2159 }
2160 switch (opc1 & 0xb /* 1011 */) {
2161 case 0x0:
2162 if (bits(machInst, 6) == 0) {
2163 if (single) {
2164 return decodeVfpRegRegRegOp<VmlaS>(
2165 machInst, vd, vn, vm, false);
2166 } else {
2167 return decodeVfpRegRegRegOp<VmlaD>(
2168 machInst, vd, vn, vm, true);
2169 }
2170 } else {
2171 if (single) {
2172 return decodeVfpRegRegRegOp<VmlsS>(
2173 machInst, vd, vn, vm, false);
2174 } else {
2175 return decodeVfpRegRegRegOp<VmlsD>(
2176 machInst, vd, vn, vm, true);
2177 }
2178 }
2179 case 0x1:
2180 if (bits(machInst, 6) == 1) {
2181 if (single) {
2182 return decodeVfpRegRegRegOp<VnmlaS>(
2183 machInst, vd, vn, vm, false);
2184 } else {
2185 return decodeVfpRegRegRegOp<VnmlaD>(
2186 machInst, vd, vn, vm, true);
2187 }
2188 } else {
2189 if (single) {
2190 return decodeVfpRegRegRegOp<VnmlsS>(
2191 machInst, vd, vn, vm, false);
2192 } else {
2193 return decodeVfpRegRegRegOp<VnmlsD>(
2194 machInst, vd, vn, vm, true);
2195 }
2196 }
2197 case 0x2:
2198 if ((opc3 & 0x1) == 0) {
2199 if (single) {
2200 return decodeVfpRegRegRegOp<VmulS>(
2201 machInst, vd, vn, vm, false);
2202 } else {
2203 return decodeVfpRegRegRegOp<VmulD>(
2204 machInst, vd, vn, vm, true);
2205 }
2206 } else {
2207 if (single) {
2208 return decodeVfpRegRegRegOp<VnmulS>(
2209 machInst, vd, vn, vm, false);
2210 } else {
2211 return decodeVfpRegRegRegOp<VnmulD>(
2212 machInst, vd, vn, vm, true);
2213 }
2214 }
2215 case 0x3:
2216 if ((opc3 & 0x1) == 0) {
2217 if (single) {
2218 return decodeVfpRegRegRegOp<VaddS>(
2219 machInst, vd, vn, vm, false);
2220 } else {
2221 return decodeVfpRegRegRegOp<VaddD>(
2222 machInst, vd, vn, vm, true);
2223 }
2224 } else {
2225 if (single) {
2226 return decodeVfpRegRegRegOp<VsubS>(
2227 machInst, vd, vn, vm, false);
2228 } else {
2229 return decodeVfpRegRegRegOp<VsubD>(
2230 machInst, vd, vn, vm, true);
2231 }
2232 }
2233 case 0x8:
2234 if ((opc3 & 0x1) == 0) {
2235 if (single) {
2236 return decodeVfpRegRegRegOp<VdivS>(
2237 machInst, vd, vn, vm, false);
2238 } else {
2239 return decodeVfpRegRegRegOp<VdivD>(
2240 machInst, vd, vn, vm, true);
2241 }
2242 }
2243 break;
2244 case 0xb:
2245 if ((opc3 & 0x1) == 0) {
2246 const uint32_t baseImm =
2247 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2248 if (single) {
2249 uint32_t imm = vfp_modified_imm(baseImm, false);
2250 return decodeVfpRegImmOp<VmovImmS>(
2251 machInst, vd, imm, false);
2252 } else {
2253 uint64_t imm = vfp_modified_imm(baseImm, true);
2254 return decodeVfpRegImmOp<VmovImmD>(
2255 machInst, vd, imm, true);
2256 }
2257 }
2258 switch (opc2) {
2259 case 0x0:
2260 if (opc3 == 1) {
2261 if (single) {
2262 return decodeVfpRegRegOp<VmovRegS>(
2263 machInst, vd, vm, false);
2264 } else {
2265 return decodeVfpRegRegOp<VmovRegD>(
2266 machInst, vd, vm, true);
2267 }
2268 } else {
2269 if (single) {
2270 return decodeVfpRegRegOp<VabsS>(
2271 machInst, vd, vm, false);
2272 } else {
2273 return decodeVfpRegRegOp<VabsD>(
2274 machInst, vd, vm, true);
2275 }
2276 }
2277 case 0x1:
2278 if (opc3 == 1) {
2279 if (single) {
2280 return decodeVfpRegRegOp<VnegS>(
2281 machInst, vd, vm, false);
2282 } else {
2283 return decodeVfpRegRegOp<VnegD>(
2284 machInst, vd, vm, true);
2285 }
2286 } else {
2287 if (single) {
2288 return decodeVfpRegRegOp<VsqrtS>(
2289 machInst, vd, vm, false);
2290 } else {
2291 return decodeVfpRegRegOp<VsqrtD>(
2292 machInst, vd, vm, true);
2293 }
2294 }
2295 case 0x2:
2296 case 0x3:
2297 {
2298 const bool toHalf = bits(machInst, 16);
2299 const bool top = bits(machInst, 7);
2300 if (top) {
2301 if (toHalf) {
2302 return new VcvtFpSFpHT(machInst, vd, vm);
2303 } else {
2304 return new VcvtFpHTFpS(machInst, vd, vm);
2305 }
2306 } else {
2307 if (toHalf) {
2308 return new VcvtFpSFpHB(machInst, vd, vm);
2309 } else {
2310 return new VcvtFpHBFpS(machInst, vd, vm);
2311 }
2312 }
2313 }
2314 case 0x4:
2315 if (single) {
2316 if (e) {
2317 return new VcmpeS(machInst, vd, vm);
2318 } else {
2319 return new VcmpS(machInst, vd, vm);
2320 }
2321 } else {
2322 if (e) {
2323 return new VcmpeD(machInst, vd, vm);
2324 } else {
2325 return new VcmpD(machInst, vd, vm);
2326 }
2327 }
2328 case 0x5:
2329 if (single) {
2330 if (e) {
2331 return new VcmpeZeroS(machInst, vd, 0);
2332 } else {
2333 return new VcmpZeroS(machInst, vd, 0);
2334 }
2335 } else {
2336 if (e) {
2337 return new VcmpeZeroD(machInst, vd, 0);
2338 } else {
2339 return new VcmpZeroD(machInst, vd, 0);
2340 }
2341 }
2342 case 0x7:
2343 if (opc3 == 0x3) {
2344 if (single) {
2345 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2346 (bits(machInst, 15, 12) << 1));
2347 return new VcvtFpSFpD(machInst, vd, vm);
2348 } else {
2349 vd = (IntRegIndex)(bits(machInst, 22) |
2350 (bits(machInst, 15, 12) << 1));
2351 return new VcvtFpDFpS(machInst, vd, vm);
2352 }
2353 }
2354 break;
2355 case 0x8:
2356 if (bits(machInst, 7) == 0) {
2357 if (single) {
2358 return new VcvtUIntFpS(machInst, vd, vm);
2359 } else {
2360 vm = (IntRegIndex)(bits(machInst, 5) |
2361 (bits(machInst, 3, 0) << 1));
2362 return new VcvtUIntFpD(machInst, vd, vm);
2363 }
2364 } else {
2365 if (single) {
2366 return new VcvtSIntFpS(machInst, vd, vm);
2367 } else {
2368 vm = (IntRegIndex)(bits(machInst, 5) |
2369 (bits(machInst, 3, 0) << 1));
2370 return new VcvtSIntFpD(machInst, vd, vm);
2371 }
2372 }
2373 case 0xa:
2374 {
2375 const bool half = (bits(machInst, 7) == 0);
2376 const uint32_t imm = bits(machInst, 5) |
2377 (bits(machInst, 3, 0) << 1);
2378 const uint32_t size =
2379 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2380 if (single) {
2381 if (half) {
2382 return new VcvtSHFixedFpS(machInst, vd, vd, size);
2383 } else {
2384 return new VcvtSFixedFpS(machInst, vd, vd, size);
2385 }
2386 } else {
2387 if (half) {
2388 return new VcvtSHFixedFpD(machInst, vd, vd, size);
2389 } else {
2390 return new VcvtSFixedFpD(machInst, vd, vd, size);
2391 }
2392 }
2393 }
2394 case 0xb:
2395 {
2396 const bool half = (bits(machInst, 7) == 0);
2397 const uint32_t imm = bits(machInst, 5) |
2398 (bits(machInst, 3, 0) << 1);
2399 const uint32_t size =
2400 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2401 if (single) {
2402 if (half) {
2403 return new VcvtUHFixedFpS(machInst, vd, vd, size);
2404 } else {
2405 return new VcvtUFixedFpS(machInst, vd, vd, size);
2406 }
2407 } else {
2408 if (half) {
2409 return new VcvtUHFixedFpD(machInst, vd, vd, size);
2410 } else {
2411 return new VcvtUFixedFpD(machInst, vd, vd, size);
2412 }
2413 }
2414 }
2415 case 0xc:
2416 if (bits(machInst, 7) == 0) {
2417 if (single) {
2418 return new VcvtFpUIntSR(machInst, vd, vm);
2419 } else {
2420 vd = (IntRegIndex)(bits(machInst, 22) |
2421 (bits(machInst, 15, 12) << 1));
2422 return new VcvtFpUIntDR(machInst, vd, vm);
2423 }
2424 } else {
2425 if (single) {
2426 return new VcvtFpUIntS(machInst, vd, vm);
2427 } else {
2428 vd = (IntRegIndex)(bits(machInst, 22) |
2429 (bits(machInst, 15, 12) << 1));
2430 return new VcvtFpUIntD(machInst, vd, vm);
2431 }
2432 }
2433 case 0xd:
2434 if (bits(machInst, 7) == 0) {
2435 if (single) {
2436 return new VcvtFpSIntSR(machInst, vd, vm);
2437 } else {
2438 vd = (IntRegIndex)(bits(machInst, 22) |
2439 (bits(machInst, 15, 12) << 1));
2440 return new VcvtFpSIntDR(machInst, vd, vm);
2441 }
2442 } else {
2443 if (single) {
2444 return new VcvtFpSIntS(machInst, vd, vm);
2445 } else {
2446 vd = (IntRegIndex)(bits(machInst, 22) |
2447 (bits(machInst, 15, 12) << 1));
2448 return new VcvtFpSIntD(machInst, vd, vm);
2449 }
2450 }
2451 case 0xe:
2452 {
2453 const bool half = (bits(machInst, 7) == 0);
2454 const uint32_t imm = bits(machInst, 5) |
2455 (bits(machInst, 3, 0) << 1);
2456 const uint32_t size =
2457 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2458 if (single) {
2459 if (half) {
2460 return new VcvtFpSHFixedS(machInst, vd, vd, size);
2461 } else {
2462 return new VcvtFpSFixedS(machInst, vd, vd, size);
2463 }
2464 } else {
2465 if (half) {
2466 return new VcvtFpSHFixedD(machInst, vd, vd, size);
2467 } else {
2468 return new VcvtFpSFixedD(machInst, vd, vd, size);
2469 }
2470 }
2471 }
2472 case 0xf:
2473 {
2474 const bool half = (bits(machInst, 7) == 0);
2475 const uint32_t imm = bits(machInst, 5) |
2476 (bits(machInst, 3, 0) << 1);
2477 const uint32_t size =
2478 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2479 if (single) {
2480 if (half) {
2481 return new VcvtFpUHFixedS(machInst, vd, vd, size);
2482 } else {
2483 return new VcvtFpUFixedS(machInst, vd, vd, size);
2484 }
2485 } else {
2486 if (half) {
2487 return new VcvtFpUHFixedD(machInst, vd, vd, size);
2488 } else {
2489 return new VcvtFpUFixedD(machInst, vd, vd, size);
2490 }
2491 }
2492 }
2493 }
2494 break;
2495 }
2496 return new Unknown(machInst);
2497 }
2498 '''
2499}};
2500
2501def format VfpData() {{
2502 decode_block = '''
2503 return decodeVfpData(machInst);
2504 '''
2505}};
1548 q, size, machInst, vd, vm);
1549 case 0x2:
1550 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1551 q, size, machInst, vd, vm);
1552 case 0x3:
1553 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1554 q, size, machInst, vd, vm);
1555 case 0x4:
1556 if (b == 0x8) {
1557 return decodeNeonUTwoMiscUSReg<NVmovn>(
1558 size, machInst, vd, vm);
1559 } else {
1560 return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1561 size, machInst, vd, vm);
1562 }
1563 case 0x5:
1564 if (q) {
1565 return decodeNeonUTwoMiscUSReg<NVqmovun>(
1566 size, machInst, vd, vm);
1567 } else {
1568 return decodeNeonSTwoMiscUSReg<NVqmovn>(
1569 size, machInst, vd, vm);
1570 }
1571 case 0x6:
1572 if (b == 0xc) {
1573 const IntRegIndex vd =
1574 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1575 (bits(machInst, 22) << 4)));
1576 const IntRegIndex vm =
1577 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1578 (bits(machInst, 5) << 4)));
1579 unsigned size = bits(machInst, 19, 18);
1580 return decodeNeonSTwoShiftUSReg<NVshll>(
1581 size, machInst, vd, vm, 8 << size);
1582 } else {
1583 return new Unknown(machInst);
1584 }
1585 case 0xc:
1586 case 0xe:
1587 if (b == 0x18) {
1588 if (size != 1 || (vm % 2))
1589 return new Unknown(machInst);
1590 return new NVcvts2h<uint16_t>(machInst, vd, vm);
1591 } else if (b == 0x1c) {
1592 if (size != 1 || (vd % 2))
1593 return new Unknown(machInst);
1594 return new NVcvth2s<uint16_t>(machInst, vd, vm);
1595 } else {
1596 return new Unknown(machInst);
1597 }
1598 default:
1599 return new Unknown(machInst);
1600 }
1601 case 0x3:
1602 if (bits(b, 4, 3) == 0x3) {
1603 if ((q && (vd % 2 || vm % 2)) || size != 2) {
1604 return new Unknown(machInst);
1605 } else {
1606 if (bits(b, 2)) {
1607 if (bits(b, 1)) {
1608 if (q) {
1609 return new NVcvt2ufxQ<float>(
1610 machInst, vd, vm, 0);
1611 } else {
1612 return new NVcvt2ufxD<float>(
1613 machInst, vd, vm, 0);
1614 }
1615 } else {
1616 if (q) {
1617 return new NVcvt2sfxQ<float>(
1618 machInst, vd, vm, 0);
1619 } else {
1620 return new NVcvt2sfxD<float>(
1621 machInst, vd, vm, 0);
1622 }
1623 }
1624 } else {
1625 if (bits(b, 1)) {
1626 if (q) {
1627 return new NVcvtu2fpQ<float>(
1628 machInst, vd, vm, 0);
1629 } else {
1630 return new NVcvtu2fpD<float>(
1631 machInst, vd, vm, 0);
1632 }
1633 } else {
1634 if (q) {
1635 return new NVcvts2fpQ<float>(
1636 machInst, vd, vm, 0);
1637 } else {
1638 return new NVcvts2fpD<float>(
1639 machInst, vd, vm, 0);
1640 }
1641 }
1642 }
1643 }
1644 } else if ((b & 0x1a) == 0x10) {
1645 if (bits(b, 2)) {
1646 if (q) {
1647 return new NVrecpeQFp<float>(machInst, vd, vm);
1648 } else {
1649 return new NVrecpeDFp<float>(machInst, vd, vm);
1650 }
1651 } else {
1652 if (q) {
1653 return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1654 } else {
1655 return new NVrecpeD<uint32_t>(machInst, vd, vm);
1656 }
1657 }
1658 } else if ((b & 0x1a) == 0x12) {
1659 if (bits(b, 2)) {
1660 if (q) {
1661 return new NVrsqrteQFp<float>(machInst, vd, vm);
1662 } else {
1663 return new NVrsqrteDFp<float>(machInst, vd, vm);
1664 }
1665 } else {
1666 if (q) {
1667 return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1668 } else {
1669 return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1670 }
1671 }
1672 } else {
1673 return new Unknown(machInst);
1674 }
1675 }
1676 return new Unknown(machInst);
1677 }
1678
1679 StaticInstPtr
1680 decodeNeonData(ExtMachInst machInst)
1681 {
1682 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1683 const uint32_t a = bits(machInst, 23, 19);
1684 const uint32_t b = bits(machInst, 11, 8);
1685 const uint32_t c = bits(machInst, 7, 4);
1686 if (bits(a, 4) == 0) {
1687 return decodeNeonThreeRegistersSameLength(machInst);
1688 } else if ((c & 0x9) == 1) {
1689 if ((a & 0x7) == 0) {
1690 return decodeNeonOneRegModImm(machInst);
1691 } else {
1692 return decodeNeonTwoRegAndShift(machInst);
1693 }
1694 } else if ((c & 0x9) == 9) {
1695 return decodeNeonTwoRegAndShift(machInst);
1696 } else if (bits(a, 2, 1) != 0x3) {
1697 if ((c & 0x5) == 0) {
1698 return decodeNeonThreeRegDiffLengths(machInst);
1699 } else if ((c & 0x5) == 4) {
1700 return decodeNeonTwoRegScalar(machInst);
1701 }
1702 } else if ((a & 0x16) == 0x16) {
1703 const IntRegIndex vd =
1704 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1705 (bits(machInst, 22) << 4)));
1706 const IntRegIndex vn =
1707 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1708 (bits(machInst, 7) << 4)));
1709 const IntRegIndex vm =
1710 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1711 (bits(machInst, 5) << 4)));
1712 if (!u) {
1713 if (bits(c, 0) == 0) {
1714 unsigned imm4 = bits(machInst, 11, 8);
1715 bool q = bits(machInst, 6);
1716 if (imm4 >= 16 && !q)
1717 return new Unknown(machInst);
1718 if (q) {
1719 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1720 } else {
1721 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1722 }
1723 }
1724 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1725 return decodeNeonTwoRegMisc(machInst);
1726 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1727 unsigned length = bits(machInst, 9, 8) + 1;
1728 if ((uint32_t)vn / 2 + length > 32)
1729 return new Unknown(machInst);
1730 if (bits(machInst, 6) == 0) {
1731 switch (length) {
1732 case 1:
1733 return new NVtbl1(machInst, vd, vn, vm);
1734 case 2:
1735 return new NVtbl2(machInst, vd, vn, vm);
1736 case 3:
1737 return new NVtbl3(machInst, vd, vn, vm);
1738 case 4:
1739 return new NVtbl4(machInst, vd, vn, vm);
1740 }
1741 } else {
1742 switch (length) {
1743 case 1:
1744 return new NVtbx1(machInst, vd, vn, vm);
1745 case 2:
1746 return new NVtbx2(machInst, vd, vn, vm);
1747 case 3:
1748 return new NVtbx3(machInst, vd, vn, vm);
1749 case 4:
1750 return new NVtbx4(machInst, vd, vn, vm);
1751 }
1752 }
1753 } else if (b == 0xc && (c & 0x9) == 0) {
1754 unsigned imm4 = bits(machInst, 19, 16);
1755 if (bits(imm4, 2, 0) == 0)
1756 return new Unknown(machInst);
1757 unsigned size = 0;
1758 while ((imm4 & 0x1) == 0) {
1759 size++;
1760 imm4 >>= 1;
1761 }
1762 unsigned index = imm4 >> 1;
1763 const bool q = bits(machInst, 6);
1764 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1765 q, size, machInst, vd, vm, index);
1766 }
1767 }
1768 return new Unknown(machInst);
1769 }
1770 '''
1771}};
1772
1773def format ThumbNeonMem() {{
1774 decode_block = '''
1775 return decodeNeonMem(machInst);
1776 '''
1777}};
1778
1779def format ThumbNeonData() {{
1780 decode_block = '''
1781 return decodeNeonData(machInst);
1782 '''
1783}};
1784
1785let {{
1786 header_output = '''
1787 StaticInstPtr
1788 decodeExtensionRegLoadStore(ExtMachInst machInst);
1789 '''
1790 decoder_output = '''
1791 StaticInstPtr
1792 decodeExtensionRegLoadStore(ExtMachInst machInst)
1793 {
1794 const uint32_t opcode = bits(machInst, 24, 20);
1795 const uint32_t offset = bits(machInst, 7, 0);
1796 const bool single = (bits(machInst, 8) == 0);
1797 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1798 RegIndex vd;
1799 if (single) {
1800 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1801 bits(machInst, 22));
1802 } else {
1803 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1804 (bits(machInst, 22) << 5));
1805 }
1806 switch (bits(opcode, 4, 3)) {
1807 case 0x0:
1808 if (bits(opcode, 4, 1) == 0x2 &&
1809 !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1810 !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1811 if ((bits(machInst, 7, 4) & 0xd) != 1) {
1812 break;
1813 }
1814 const IntRegIndex rt =
1815 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1816 const IntRegIndex rt2 =
1817 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1818 const bool op = bits(machInst, 20);
1819 uint32_t vm;
1820 if (single) {
1821 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1822 } else {
1823 vm = (bits(machInst, 3, 0) << 1) |
1824 (bits(machInst, 5) << 5);
1825 }
1826 if (op) {
1827 return new Vmov2Core2Reg(machInst, rt, rt2,
1828 (IntRegIndex)vm);
1829 } else {
1830 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1831 rt, rt2);
1832 }
1833 }
1834 break;
1835 case 0x1:
1836 {
1837 if (offset == 0 || vd + offset/2 > NumFloatArchRegs) {
1838 break;
1839 }
1840 switch (bits(opcode, 1, 0)) {
1841 case 0x0:
1842 return new VLdmStm(machInst, rn, vd, single,
1843 true, false, false, offset);
1844 case 0x1:
1845 return new VLdmStm(machInst, rn, vd, single,
1846 true, false, true, offset);
1847 case 0x2:
1848 return new VLdmStm(machInst, rn, vd, single,
1849 true, true, false, offset);
1850 case 0x3:
1851 // If rn == sp, then this is called vpop.
1852 return new VLdmStm(machInst, rn, vd, single,
1853 true, true, true, offset);
1854 }
1855 }
1856 case 0x2:
1857 if (bits(opcode, 1, 0) == 0x2) {
1858 // If rn == sp, then this is called vpush.
1859 return new VLdmStm(machInst, rn, vd, single,
1860 false, true, false, offset);
1861 } else if (bits(opcode, 1, 0) == 0x3) {
1862 return new VLdmStm(machInst, rn, vd, single,
1863 false, true, true, offset);
1864 }
1865 // Fall through on purpose
1866 case 0x3:
1867 const bool up = (bits(machInst, 23) == 1);
1868 const uint32_t imm = bits(machInst, 7, 0) << 2;
1869 RegIndex vd;
1870 if (single) {
1871 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1872 (bits(machInst, 22)));
1873 } else {
1874 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1875 (bits(machInst, 22) << 5));
1876 }
1877 if (bits(opcode, 1, 0) == 0x0) {
1878 if (single) {
1879 if (up) {
1880 return new %(vstr_us)s(machInst, vd, rn, up, imm);
1881 } else {
1882 return new %(vstr_s)s(machInst, vd, rn, up, imm);
1883 }
1884 } else {
1885 if (up) {
1886 return new %(vstr_ud)s(machInst, vd, vd + 1,
1887 rn, up, imm);
1888 } else {
1889 return new %(vstr_d)s(machInst, vd, vd + 1,
1890 rn, up, imm);
1891 }
1892 }
1893 } else if (bits(opcode, 1, 0) == 0x1) {
1894 if (single) {
1895 if (up) {
1896 return new %(vldr_us)s(machInst, vd, rn, up, imm);
1897 } else {
1898 return new %(vldr_s)s(machInst, vd, rn, up, imm);
1899 }
1900 } else {
1901 if (up) {
1902 return new %(vldr_ud)s(machInst, vd, vd + 1,
1903 rn, up, imm);
1904 } else {
1905 return new %(vldr_d)s(machInst, vd, vd + 1,
1906 rn, up, imm);
1907 }
1908 }
1909 }
1910 }
1911 return new Unknown(machInst);
1912 }
1913 ''' % {
1914 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1915 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1916 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1917 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1918 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1919 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1920 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1921 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1922 }
1923}};
1924
1925def format ExtensionRegLoadStore() {{
1926 decode_block = '''
1927 return decodeExtensionRegLoadStore(machInst);
1928 '''
1929}};
1930
1931let {{
1932 header_output = '''
1933 StaticInstPtr
1934 decodeShortFpTransfer(ExtMachInst machInst);
1935 '''
1936 decoder_output = '''
1937 StaticInstPtr
1938 decodeShortFpTransfer(ExtMachInst machInst)
1939 {
1940 const uint32_t l = bits(machInst, 20);
1941 const uint32_t c = bits(machInst, 8);
1942 const uint32_t a = bits(machInst, 23, 21);
1943 const uint32_t b = bits(machInst, 6, 5);
1944 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1945 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1946 return new Unknown(machInst);
1947 }
1948 if (l == 0 && c == 0) {
1949 if (a == 0) {
1950 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
1951 bits(machInst, 7);
1952 const IntRegIndex rt =
1953 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1954 if (bits(machInst, 20) == 1) {
1955 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1956 } else {
1957 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1958 }
1959 } else if (a == 0x7) {
1960 const IntRegIndex rt =
1961 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1962 uint32_t specReg = bits(machInst, 19, 16);
1963 switch (specReg) {
1964 case 0:
1965 specReg = MISCREG_FPSID;
1966 break;
1967 case 1:
1968 specReg = MISCREG_FPSCR;
1969 break;
1970 case 6:
1971 specReg = MISCREG_MVFR1;
1972 break;
1973 case 7:
1974 specReg = MISCREG_MVFR0;
1975 break;
1976 case 8:
1977 specReg = MISCREG_FPEXC;
1978 break;
1979 default:
1980 return new Unknown(machInst);
1981 }
1982 if (specReg == MISCREG_FPSCR) {
1983 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
1984 } else {
1985 return new Vmsr(machInst, (IntRegIndex)specReg, rt);
1986 }
1987 }
1988 } else if (l == 0 && c == 1) {
1989 if (bits(a, 2) == 0) {
1990 uint32_t vd = (bits(machInst, 7) << 5) |
1991 (bits(machInst, 19, 16) << 1);
1992 // Handle accessing each single precision half of the vector.
1993 vd += bits(machInst, 21);
1994 const IntRegIndex rt =
1995 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1996 if (bits(machInst, 22) == 1) {
1997 return new VmovCoreRegB(machInst, (IntRegIndex)vd,
1998 rt, bits(machInst, 6, 5));
1999 } else if (bits(machInst, 5) == 1) {
2000 return new VmovCoreRegH(machInst, (IntRegIndex)vd,
2001 rt, bits(machInst, 6));
2002 } else if (bits(machInst, 6) == 0) {
2003 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2004 } else {
2005 return new Unknown(machInst);
2006 }
2007 } else if (bits(b, 1) == 0) {
2008 bool q = bits(machInst, 21);
2009 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2010 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2011 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2012 IntRegIndex rt = (IntRegIndex)(uint32_t)
2013 bits(machInst, 15, 12);
2014 if (q) {
2015 switch (be) {
2016 case 0:
2017 return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2018 case 1:
2019 return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2020 case 2:
2021 return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2022 case 3:
2023 return new Unknown(machInst);
2024 }
2025 } else {
2026 switch (be) {
2027 case 0:
2028 return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2029 case 1:
2030 return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2031 case 2:
2032 return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2033 case 3:
2034 return new Unknown(machInst);
2035 }
2036 }
2037 }
2038 } else if (l == 1 && c == 0) {
2039 if (a == 0) {
2040 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2041 bits(machInst, 7);
2042 const IntRegIndex rt =
2043 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2044 if (bits(machInst, 20) == 1) {
2045 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2046 } else {
2047 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2048 }
2049 } else if (a == 7) {
2050 const IntRegIndex rt =
2051 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2052 uint32_t specReg = bits(machInst, 19, 16);
2053 switch (specReg) {
2054 case 0:
2055 specReg = MISCREG_FPSID;
2056 break;
2057 case 1:
2058 specReg = MISCREG_FPSCR;
2059 break;
2060 case 6:
2061 specReg = MISCREG_MVFR1;
2062 break;
2063 case 7:
2064 specReg = MISCREG_MVFR0;
2065 break;
2066 case 8:
2067 specReg = MISCREG_FPEXC;
2068 break;
2069 default:
2070 return new Unknown(machInst);
2071 }
2072 if (rt == 0xf) {
2073 if (specReg == MISCREG_FPSCR) {
2074 return new VmrsApsrFpscr(machInst);
2075 } else {
2076 return new Unknown(machInst);
2077 }
2078 } else if (specReg == MISCREG_FPSCR) {
2079 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2080 } else {
2081 return new Vmrs(machInst, rt, (IntRegIndex)specReg);
2082 }
2083 }
2084 } else {
2085 uint32_t vd = (bits(machInst, 7) << 5) |
2086 (bits(machInst, 19, 16) << 1);
2087 // Handle indexing into each single precision half of the vector.
2088 vd += bits(machInst, 21);
2089 uint32_t index;
2090 const IntRegIndex rt =
2091 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2092 const bool u = (bits(machInst, 23) == 1);
2093 if (bits(machInst, 22) == 1) {
2094 index = bits(machInst, 6, 5);
2095 if (u) {
2096 return new VmovRegCoreUB(machInst, rt,
2097 (IntRegIndex)vd, index);
2098 } else {
2099 return new VmovRegCoreSB(machInst, rt,
2100 (IntRegIndex)vd, index);
2101 }
2102 } else if (bits(machInst, 5) == 1) {
2103 index = bits(machInst, 6);
2104 if (u) {
2105 return new VmovRegCoreUH(machInst, rt,
2106 (IntRegIndex)vd, index);
2107 } else {
2108 return new VmovRegCoreSH(machInst, rt,
2109 (IntRegIndex)vd, index);
2110 }
2111 } else if (bits(machInst, 6) == 0 && !u) {
2112 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2113 } else {
2114 return new Unknown(machInst);
2115 }
2116 }
2117 return new Unknown(machInst);
2118 }
2119 '''
2120}};
2121
2122def format ShortFpTransfer() {{
2123 decode_block = '''
2124 return decodeShortFpTransfer(machInst);
2125 '''
2126}};
2127
2128let {{
2129 header_output = '''
2130 StaticInstPtr
2131 decodeVfpData(ExtMachInst machInst);
2132 '''
2133 decoder_output = '''
2134 StaticInstPtr
2135 decodeVfpData(ExtMachInst machInst)
2136 {
2137 const uint32_t opc1 = bits(machInst, 23, 20);
2138 const uint32_t opc2 = bits(machInst, 19, 16);
2139 const uint32_t opc3 = bits(machInst, 7, 6);
2140 //const uint32_t opc4 = bits(machInst, 3, 0);
2141 const bool single = (bits(machInst, 8) == 0);
2142 // Used to select between vcmp and vcmpe.
2143 const bool e = (bits(machInst, 7) == 1);
2144 IntRegIndex vd;
2145 IntRegIndex vm;
2146 IntRegIndex vn;
2147 if (single) {
2148 vd = (IntRegIndex)(bits(machInst, 22) |
2149 (bits(machInst, 15, 12) << 1));
2150 vm = (IntRegIndex)(bits(machInst, 5) |
2151 (bits(machInst, 3, 0) << 1));
2152 vn = (IntRegIndex)(bits(machInst, 7) |
2153 (bits(machInst, 19, 16) << 1));
2154 } else {
2155 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2156 (bits(machInst, 15, 12) << 1));
2157 vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2158 (bits(machInst, 3, 0) << 1));
2159 vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2160 (bits(machInst, 19, 16) << 1));
2161 }
2162 switch (opc1 & 0xb /* 1011 */) {
2163 case 0x0:
2164 if (bits(machInst, 6) == 0) {
2165 if (single) {
2166 return decodeVfpRegRegRegOp<VmlaS>(
2167 machInst, vd, vn, vm, false);
2168 } else {
2169 return decodeVfpRegRegRegOp<VmlaD>(
2170 machInst, vd, vn, vm, true);
2171 }
2172 } else {
2173 if (single) {
2174 return decodeVfpRegRegRegOp<VmlsS>(
2175 machInst, vd, vn, vm, false);
2176 } else {
2177 return decodeVfpRegRegRegOp<VmlsD>(
2178 machInst, vd, vn, vm, true);
2179 }
2180 }
2181 case 0x1:
2182 if (bits(machInst, 6) == 1) {
2183 if (single) {
2184 return decodeVfpRegRegRegOp<VnmlaS>(
2185 machInst, vd, vn, vm, false);
2186 } else {
2187 return decodeVfpRegRegRegOp<VnmlaD>(
2188 machInst, vd, vn, vm, true);
2189 }
2190 } else {
2191 if (single) {
2192 return decodeVfpRegRegRegOp<VnmlsS>(
2193 machInst, vd, vn, vm, false);
2194 } else {
2195 return decodeVfpRegRegRegOp<VnmlsD>(
2196 machInst, vd, vn, vm, true);
2197 }
2198 }
2199 case 0x2:
2200 if ((opc3 & 0x1) == 0) {
2201 if (single) {
2202 return decodeVfpRegRegRegOp<VmulS>(
2203 machInst, vd, vn, vm, false);
2204 } else {
2205 return decodeVfpRegRegRegOp<VmulD>(
2206 machInst, vd, vn, vm, true);
2207 }
2208 } else {
2209 if (single) {
2210 return decodeVfpRegRegRegOp<VnmulS>(
2211 machInst, vd, vn, vm, false);
2212 } else {
2213 return decodeVfpRegRegRegOp<VnmulD>(
2214 machInst, vd, vn, vm, true);
2215 }
2216 }
2217 case 0x3:
2218 if ((opc3 & 0x1) == 0) {
2219 if (single) {
2220 return decodeVfpRegRegRegOp<VaddS>(
2221 machInst, vd, vn, vm, false);
2222 } else {
2223 return decodeVfpRegRegRegOp<VaddD>(
2224 machInst, vd, vn, vm, true);
2225 }
2226 } else {
2227 if (single) {
2228 return decodeVfpRegRegRegOp<VsubS>(
2229 machInst, vd, vn, vm, false);
2230 } else {
2231 return decodeVfpRegRegRegOp<VsubD>(
2232 machInst, vd, vn, vm, true);
2233 }
2234 }
2235 case 0x8:
2236 if ((opc3 & 0x1) == 0) {
2237 if (single) {
2238 return decodeVfpRegRegRegOp<VdivS>(
2239 machInst, vd, vn, vm, false);
2240 } else {
2241 return decodeVfpRegRegRegOp<VdivD>(
2242 machInst, vd, vn, vm, true);
2243 }
2244 }
2245 break;
2246 case 0xb:
2247 if ((opc3 & 0x1) == 0) {
2248 const uint32_t baseImm =
2249 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2250 if (single) {
2251 uint32_t imm = vfp_modified_imm(baseImm, false);
2252 return decodeVfpRegImmOp<VmovImmS>(
2253 machInst, vd, imm, false);
2254 } else {
2255 uint64_t imm = vfp_modified_imm(baseImm, true);
2256 return decodeVfpRegImmOp<VmovImmD>(
2257 machInst, vd, imm, true);
2258 }
2259 }
2260 switch (opc2) {
2261 case 0x0:
2262 if (opc3 == 1) {
2263 if (single) {
2264 return decodeVfpRegRegOp<VmovRegS>(
2265 machInst, vd, vm, false);
2266 } else {
2267 return decodeVfpRegRegOp<VmovRegD>(
2268 machInst, vd, vm, true);
2269 }
2270 } else {
2271 if (single) {
2272 return decodeVfpRegRegOp<VabsS>(
2273 machInst, vd, vm, false);
2274 } else {
2275 return decodeVfpRegRegOp<VabsD>(
2276 machInst, vd, vm, true);
2277 }
2278 }
2279 case 0x1:
2280 if (opc3 == 1) {
2281 if (single) {
2282 return decodeVfpRegRegOp<VnegS>(
2283 machInst, vd, vm, false);
2284 } else {
2285 return decodeVfpRegRegOp<VnegD>(
2286 machInst, vd, vm, true);
2287 }
2288 } else {
2289 if (single) {
2290 return decodeVfpRegRegOp<VsqrtS>(
2291 machInst, vd, vm, false);
2292 } else {
2293 return decodeVfpRegRegOp<VsqrtD>(
2294 machInst, vd, vm, true);
2295 }
2296 }
2297 case 0x2:
2298 case 0x3:
2299 {
2300 const bool toHalf = bits(machInst, 16);
2301 const bool top = bits(machInst, 7);
2302 if (top) {
2303 if (toHalf) {
2304 return new VcvtFpSFpHT(machInst, vd, vm);
2305 } else {
2306 return new VcvtFpHTFpS(machInst, vd, vm);
2307 }
2308 } else {
2309 if (toHalf) {
2310 return new VcvtFpSFpHB(machInst, vd, vm);
2311 } else {
2312 return new VcvtFpHBFpS(machInst, vd, vm);
2313 }
2314 }
2315 }
2316 case 0x4:
2317 if (single) {
2318 if (e) {
2319 return new VcmpeS(machInst, vd, vm);
2320 } else {
2321 return new VcmpS(machInst, vd, vm);
2322 }
2323 } else {
2324 if (e) {
2325 return new VcmpeD(machInst, vd, vm);
2326 } else {
2327 return new VcmpD(machInst, vd, vm);
2328 }
2329 }
2330 case 0x5:
2331 if (single) {
2332 if (e) {
2333 return new VcmpeZeroS(machInst, vd, 0);
2334 } else {
2335 return new VcmpZeroS(machInst, vd, 0);
2336 }
2337 } else {
2338 if (e) {
2339 return new VcmpeZeroD(machInst, vd, 0);
2340 } else {
2341 return new VcmpZeroD(machInst, vd, 0);
2342 }
2343 }
2344 case 0x7:
2345 if (opc3 == 0x3) {
2346 if (single) {
2347 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2348 (bits(machInst, 15, 12) << 1));
2349 return new VcvtFpSFpD(machInst, vd, vm);
2350 } else {
2351 vd = (IntRegIndex)(bits(machInst, 22) |
2352 (bits(machInst, 15, 12) << 1));
2353 return new VcvtFpDFpS(machInst, vd, vm);
2354 }
2355 }
2356 break;
2357 case 0x8:
2358 if (bits(machInst, 7) == 0) {
2359 if (single) {
2360 return new VcvtUIntFpS(machInst, vd, vm);
2361 } else {
2362 vm = (IntRegIndex)(bits(machInst, 5) |
2363 (bits(machInst, 3, 0) << 1));
2364 return new VcvtUIntFpD(machInst, vd, vm);
2365 }
2366 } else {
2367 if (single) {
2368 return new VcvtSIntFpS(machInst, vd, vm);
2369 } else {
2370 vm = (IntRegIndex)(bits(machInst, 5) |
2371 (bits(machInst, 3, 0) << 1));
2372 return new VcvtSIntFpD(machInst, vd, vm);
2373 }
2374 }
2375 case 0xa:
2376 {
2377 const bool half = (bits(machInst, 7) == 0);
2378 const uint32_t imm = bits(machInst, 5) |
2379 (bits(machInst, 3, 0) << 1);
2380 const uint32_t size =
2381 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2382 if (single) {
2383 if (half) {
2384 return new VcvtSHFixedFpS(machInst, vd, vd, size);
2385 } else {
2386 return new VcvtSFixedFpS(machInst, vd, vd, size);
2387 }
2388 } else {
2389 if (half) {
2390 return new VcvtSHFixedFpD(machInst, vd, vd, size);
2391 } else {
2392 return new VcvtSFixedFpD(machInst, vd, vd, size);
2393 }
2394 }
2395 }
2396 case 0xb:
2397 {
2398 const bool half = (bits(machInst, 7) == 0);
2399 const uint32_t imm = bits(machInst, 5) |
2400 (bits(machInst, 3, 0) << 1);
2401 const uint32_t size =
2402 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2403 if (single) {
2404 if (half) {
2405 return new VcvtUHFixedFpS(machInst, vd, vd, size);
2406 } else {
2407 return new VcvtUFixedFpS(machInst, vd, vd, size);
2408 }
2409 } else {
2410 if (half) {
2411 return new VcvtUHFixedFpD(machInst, vd, vd, size);
2412 } else {
2413 return new VcvtUFixedFpD(machInst, vd, vd, size);
2414 }
2415 }
2416 }
2417 case 0xc:
2418 if (bits(machInst, 7) == 0) {
2419 if (single) {
2420 return new VcvtFpUIntSR(machInst, vd, vm);
2421 } else {
2422 vd = (IntRegIndex)(bits(machInst, 22) |
2423 (bits(machInst, 15, 12) << 1));
2424 return new VcvtFpUIntDR(machInst, vd, vm);
2425 }
2426 } else {
2427 if (single) {
2428 return new VcvtFpUIntS(machInst, vd, vm);
2429 } else {
2430 vd = (IntRegIndex)(bits(machInst, 22) |
2431 (bits(machInst, 15, 12) << 1));
2432 return new VcvtFpUIntD(machInst, vd, vm);
2433 }
2434 }
2435 case 0xd:
2436 if (bits(machInst, 7) == 0) {
2437 if (single) {
2438 return new VcvtFpSIntSR(machInst, vd, vm);
2439 } else {
2440 vd = (IntRegIndex)(bits(machInst, 22) |
2441 (bits(machInst, 15, 12) << 1));
2442 return new VcvtFpSIntDR(machInst, vd, vm);
2443 }
2444 } else {
2445 if (single) {
2446 return new VcvtFpSIntS(machInst, vd, vm);
2447 } else {
2448 vd = (IntRegIndex)(bits(machInst, 22) |
2449 (bits(machInst, 15, 12) << 1));
2450 return new VcvtFpSIntD(machInst, vd, vm);
2451 }
2452 }
2453 case 0xe:
2454 {
2455 const bool half = (bits(machInst, 7) == 0);
2456 const uint32_t imm = bits(machInst, 5) |
2457 (bits(machInst, 3, 0) << 1);
2458 const uint32_t size =
2459 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2460 if (single) {
2461 if (half) {
2462 return new VcvtFpSHFixedS(machInst, vd, vd, size);
2463 } else {
2464 return new VcvtFpSFixedS(machInst, vd, vd, size);
2465 }
2466 } else {
2467 if (half) {
2468 return new VcvtFpSHFixedD(machInst, vd, vd, size);
2469 } else {
2470 return new VcvtFpSFixedD(machInst, vd, vd, size);
2471 }
2472 }
2473 }
2474 case 0xf:
2475 {
2476 const bool half = (bits(machInst, 7) == 0);
2477 const uint32_t imm = bits(machInst, 5) |
2478 (bits(machInst, 3, 0) << 1);
2479 const uint32_t size =
2480 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2481 if (single) {
2482 if (half) {
2483 return new VcvtFpUHFixedS(machInst, vd, vd, size);
2484 } else {
2485 return new VcvtFpUFixedS(machInst, vd, vd, size);
2486 }
2487 } else {
2488 if (half) {
2489 return new VcvtFpUHFixedD(machInst, vd, vd, size);
2490 } else {
2491 return new VcvtFpUFixedD(machInst, vd, vd, size);
2492 }
2493 }
2494 }
2495 }
2496 break;
2497 }
2498 return new Unknown(machInst);
2499 }
2500 '''
2501}};
2502
2503def format VfpData() {{
2504 decode_block = '''
2505 return decodeVfpData(machInst);
2506 '''
2507}};