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