arm: Add support for ARMv8 (AArch64 & AArch32)
[gem5.git] / src / arch / arm / isa / formats / aarch64.isa
1 // Copyright (c) 2011-2013 ARM Limited
2 // All rights reserved
3 //
4 // The license below extends only to copyright in the software and shall
5 // not be construed as granting a license to any other intellectual
6 // property including but not limited to intellectual property relating
7 // to a hardware implementation of the functionality of the software
8 // licensed hereunder. You may use the software subject to the license
9 // terms below provided that you ensure that this notice is replicated
10 // unmodified and in its entirety in all distributions of the software,
11 // modified or unmodified, in source code or in binary form.
12 //
13 // Redistribution and use in source and binary forms, with or without
14 // modification, are permitted provided that the following conditions are
15 // met: redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer;
17 // redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution;
20 // neither the name of the copyright holders nor the names of its
21 // contributors may be used to endorse or promote products derived from
22 // this software without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 //
36 // Authors: Gabe Black
37 // Thomas Grocutt
38 // Mbou Eyole
39 // Giacomo Gabrielli
40
41 output header {{
42 namespace Aarch64
43 {
44 StaticInstPtr decodeDataProcImm(ExtMachInst machInst);
45 StaticInstPtr decodeBranchExcSys(ExtMachInst machInst);
46 StaticInstPtr decodeLoadsStores(ExtMachInst machInst);
47 StaticInstPtr decodeDataProcReg(ExtMachInst machInst);
48
49 StaticInstPtr decodeFpAdvSIMD(ExtMachInst machInst);
50 StaticInstPtr decodeFp(ExtMachInst machInst);
51 StaticInstPtr decodeAdvSIMD(ExtMachInst machInst);
52 StaticInstPtr decodeAdvSIMDScalar(ExtMachInst machInst);
53
54 StaticInstPtr decodeGem5Ops(ExtMachInst machInst);
55 }
56 }};
57
58 output decoder {{
59 namespace Aarch64
60 {
61 StaticInstPtr
62 decodeDataProcImm(ExtMachInst machInst)
63 {
64 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
65 IntRegIndex rdsp = makeSP(rd);
66 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
67 IntRegIndex rnsp = makeSP(rn);
68
69 uint8_t opc = bits(machInst, 30, 29);
70 bool sf = bits(machInst, 31);
71 bool n = bits(machInst, 22);
72 uint8_t immr = bits(machInst, 21, 16);
73 uint8_t imms = bits(machInst, 15, 10);
74 switch (bits(machInst, 25, 23)) {
75 case 0x0:
76 case 0x1:
77 {
78 uint64_t immlo = bits(machInst, 30, 29);
79 uint64_t immhi = bits(machInst, 23, 5);
80 uint64_t imm = (immlo << 0) | (immhi << 2);
81 if (bits(machInst, 31) == 0)
82 return new AdrXImm(machInst, rd, INTREG_ZERO, sext<21>(imm));
83 else
84 return new AdrpXImm(machInst, rd, INTREG_ZERO,
85 sext<33>(imm << 12));
86 }
87 case 0x2:
88 case 0x3:
89 {
90 uint32_t imm12 = bits(machInst, 21, 10);
91 uint8_t shift = bits(machInst, 23, 22);
92 uint32_t imm;
93 if (shift == 0x0)
94 imm = imm12 << 0;
95 else if (shift == 0x1)
96 imm = imm12 << 12;
97 else
98 return new Unknown64(machInst);
99 switch (opc) {
100 case 0x0:
101 return new AddXImm(machInst, rdsp, rnsp, imm);
102 case 0x1:
103 return new AddXImmCc(machInst, rd, rnsp, imm);
104 case 0x2:
105 return new SubXImm(machInst, rdsp, rnsp, imm);
106 case 0x3:
107 return new SubXImmCc(machInst, rd, rnsp, imm);
108 }
109 }
110 case 0x4:
111 {
112 if (!sf && n)
113 return new Unknown64(machInst);
114 // len = MSB(n:NOT(imms)), len < 1 is undefined.
115 uint8_t len = 0;
116 if (n) {
117 len = 6;
118 } else if (imms == 0x3f || imms == 0x3e) {
119 return new Unknown64(machInst);
120 } else {
121 len = findMsbSet(imms ^ 0x3f);
122 }
123 // Generate r, s, and size.
124 uint64_t r = bits(immr, len - 1, 0);
125 uint64_t s = bits(imms, len - 1, 0);
126 uint8_t size = 1 << len;
127 if (s == size - 1)
128 return new Unknown64(machInst);
129 // Generate the pattern with s 1s, rotated by r, with size bits.
130 uint64_t pattern = mask(s + 1);
131 if (r) {
132 pattern = (pattern >> r) | (pattern << (size - r));
133 pattern &= mask(size);
134 }
135 uint8_t width = sf ? 64 : 32;
136 // Replicate that to fill up the immediate.
137 for (unsigned i = 1; i < (width / size); i *= 2)
138 pattern |= (pattern << (i * size));
139 uint64_t imm = pattern;
140
141 switch (opc) {
142 case 0x0:
143 return new AndXImm(machInst, rdsp, rn, imm);
144 case 0x1:
145 return new OrrXImm(machInst, rdsp, rn, imm);
146 case 0x2:
147 return new EorXImm(machInst, rdsp, rn, imm);
148 case 0x3:
149 return new AndXImmCc(machInst, rd, rn, imm);
150 }
151 }
152 case 0x5:
153 {
154 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
155 uint32_t imm16 = bits(machInst, 20, 5);
156 uint32_t hw = bits(machInst, 22, 21);
157 switch (opc) {
158 case 0x0:
159 return new Movn(machInst, rd, imm16, hw * 16);
160 case 0x1:
161 return new Unknown64(machInst);
162 case 0x2:
163 return new Movz(machInst, rd, imm16, hw * 16);
164 case 0x3:
165 return new Movk(machInst, rd, imm16, hw * 16);
166 }
167 }
168 case 0x6:
169 if ((sf != n) || (!sf && (bits(immr, 5) || bits(imms, 5))))
170 return new Unknown64(machInst);
171 switch (opc) {
172 case 0x0:
173 return new Sbfm64(machInst, rd, rn, immr, imms);
174 case 0x1:
175 return new Bfm64(machInst, rd, rn, immr, imms);
176 case 0x2:
177 return new Ubfm64(machInst, rd, rn, immr, imms);
178 case 0x3:
179 return new Unknown64(machInst);
180 }
181 case 0x7:
182 {
183 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
184 if (opc || bits(machInst, 21))
185 return new Unknown64(machInst);
186 else
187 return new Extr64(machInst, rd, rn, rm, imms);
188 }
189 }
190 return new FailUnimplemented("Unhandled Case8", machInst);
191 }
192 }
193 }};
194
195 output decoder {{
196 namespace Aarch64
197 {
198 StaticInstPtr
199 decodeBranchExcSys(ExtMachInst machInst)
200 {
201 switch (bits(machInst, 30, 29)) {
202 case 0x0:
203 {
204 int64_t imm = sext<26>(bits(machInst, 25, 0)) << 2;
205 if (bits(machInst, 31) == 0)
206 return new B64(machInst, imm);
207 else
208 return new Bl64(machInst, imm);
209 }
210 case 0x1:
211 {
212 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
213 if (bits(machInst, 25) == 0) {
214 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
215 if (bits(machInst, 24) == 0)
216 return new Cbz64(machInst, imm, rt);
217 else
218 return new Cbnz64(machInst, imm, rt);
219 } else {
220 uint64_t bitmask = 0x1;
221 bitmask <<= bits(machInst, 23, 19);
222 int64_t imm = sext<14>(bits(machInst, 18, 5)) << 2;
223 if (bits(machInst, 31))
224 bitmask <<= 32;
225 if (bits(machInst, 24) == 0)
226 return new Tbz64(machInst, bitmask, imm, rt);
227 else
228 return new Tbnz64(machInst, bitmask, imm, rt);
229 }
230 }
231 case 0x2:
232 // bit 30:26=10101
233 if (bits(machInst, 31) == 0) {
234 if (bits(machInst, 25, 24) || bits(machInst, 4))
235 return new Unknown64(machInst);
236 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
237 ConditionCode condCode =
238 (ConditionCode)(uint8_t)(bits(machInst, 3, 0));
239 return new BCond64(machInst, imm, condCode);
240 } else if (bits(machInst, 25, 24) == 0x0) {
241 if (bits(machInst, 4, 2))
242 return new Unknown64(machInst);
243 uint8_t decVal = (bits(machInst, 1, 0) << 0) |
244 (bits(machInst, 23, 21) << 2);
245 switch (decVal) {
246 case 0x01:
247 return new Svc64(machInst);
248 case 0x02:
249 return new FailUnimplemented("hvc", machInst);
250 case 0x03:
251 return new Smc64(machInst);
252 case 0x04:
253 return new FailUnimplemented("brk", machInst);
254 case 0x08:
255 return new FailUnimplemented("hlt", machInst);
256 case 0x15:
257 return new FailUnimplemented("dcps1", machInst);
258 case 0x16:
259 return new FailUnimplemented("dcps2", machInst);
260 case 0x17:
261 return new FailUnimplemented("dcps3", machInst);
262 default:
263 return new Unknown64(machInst);
264 }
265 } else if (bits(machInst, 25, 22) == 0x4) {
266 // bit 31:22=1101010100
267 bool l = bits(machInst, 21);
268 uint8_t op0 = bits(machInst, 20, 19);
269 uint8_t op1 = bits(machInst, 18, 16);
270 uint8_t crn = bits(machInst, 15, 12);
271 uint8_t crm = bits(machInst, 11, 8);
272 uint8_t op2 = bits(machInst, 7, 5);
273 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
274 switch (op0) {
275 case 0x0:
276 if (rt != 0x1f || l)
277 return new Unknown64(machInst);
278 if (crn == 0x2 && op1 == 0x3) {
279 switch (op2) {
280 case 0x0:
281 return new NopInst(machInst);
282 case 0x1:
283 return new YieldInst(machInst);
284 case 0x2:
285 return new WfeInst(machInst);
286 case 0x3:
287 return new WfiInst(machInst);
288 case 0x4:
289 return new SevInst(machInst);
290 case 0x5:
291 return new SevlInst(machInst);
292 default:
293 return new Unknown64(machInst);
294 }
295 } else if (crn == 0x3 && op1 == 0x3) {
296 switch (op2) {
297 case 0x2:
298 return new Clrex64(machInst);
299 case 0x4:
300 return new Dsb64(machInst);
301 case 0x5:
302 return new Dmb64(machInst);
303 case 0x6:
304 return new Isb64(machInst);
305 default:
306 return new Unknown64(machInst);
307 }
308 } else if (crn == 0x4) {
309 // MSR immediate
310 switch (op1 << 3 | op2) {
311 case 0x5:
312 // SP
313 return new MsrSP64(machInst,
314 (IntRegIndex) MISCREG_SPSEL,
315 INTREG_ZERO,
316 crm & 0x1);
317 case 0x1e:
318 // DAIFSet
319 return new MsrDAIFSet64(
320 machInst,
321 (IntRegIndex) MISCREG_DAIF,
322 INTREG_ZERO,
323 crm);
324 case 0x1f:
325 // DAIFClr
326 return new MsrDAIFClr64(
327 machInst,
328 (IntRegIndex) MISCREG_DAIF,
329 INTREG_ZERO,
330 crm);
331 default:
332 return new Unknown64(machInst);
333 }
334 } else {
335 return new Unknown64(machInst);
336 }
337 break;
338 case 0x1:
339 case 0x2:
340 case 0x3:
341 {
342 // bit 31:22=1101010100, 20:19=11
343 bool read = l;
344 MiscRegIndex miscReg =
345 decodeAArch64SysReg(op0, op1, crn, crm, op2);
346 if (read) {
347 if ((miscReg == MISCREG_DC_CIVAC_Xt) ||
348 (miscReg == MISCREG_DC_CVAC_Xt) ||
349 (miscReg == MISCREG_DC_ZVA_Xt)) {
350 return new Unknown64(machInst);
351 }
352 }
353 // Check for invalid registers
354 if (miscReg == MISCREG_UNKNOWN) {
355 return new Unknown64(machInst);
356 } else if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) {
357 if (miscReg == MISCREG_NZCV) {
358 if (read)
359 return new MrsNZCV64(machInst, rt, (IntRegIndex) miscReg);
360 else
361 return new MsrNZCV64(machInst, (IntRegIndex) miscReg, rt);
362 }
363 uint32_t iss = msrMrs64IssBuild(read, op0, op1, crn, crm, op2, rt);
364 if (miscReg == MISCREG_DC_ZVA_Xt && !read)
365 return new Dczva(machInst, rt, (IntRegIndex) miscReg, iss);
366
367 if (read)
368 return new Mrs64(machInst, rt, (IntRegIndex) miscReg, iss);
369 else
370 return new Msr64(machInst, (IntRegIndex) miscReg, rt, iss);
371 } else if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) {
372 std::string full_mnem = csprintf("%s %s",
373 read ? "mrs" : "msr", miscRegName[miscReg]);
374 return new WarnUnimplemented(read ? "mrs" : "msr",
375 machInst, full_mnem);
376 } else {
377 return new FailUnimplemented(csprintf("%s %s",
378 read ? "mrs" : "msr", miscRegName[miscReg]).c_str(),
379 machInst);
380 }
381 }
382 break;
383 }
384 } else if (bits(machInst, 25) == 0x1) {
385 uint8_t opc = bits(machInst, 24, 21);
386 uint8_t op2 = bits(machInst, 20, 16);
387 uint8_t op3 = bits(machInst, 15, 10);
388 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
389 uint8_t op4 = bits(machInst, 4, 0);
390 if (op2 != 0x1f || op3 != 0x0 || op4 != 0x0)
391 return new Unknown64(machInst);
392 switch (opc) {
393 case 0x0:
394 return new Br64(machInst, rn);
395 case 0x1:
396 return new Blr64(machInst, rn);
397 case 0x2:
398 return new Ret64(machInst, rn);
399 case 0x4:
400 if (rn != 0x1f)
401 return new Unknown64(machInst);
402 return new Eret64(machInst);
403 case 0x5:
404 if (rn != 0x1f)
405 return new Unknown64(machInst);
406 return new FailUnimplemented("dret", machInst);
407 }
408 }
409 default:
410 return new Unknown64(machInst);
411 }
412 return new FailUnimplemented("Unhandled Case7", machInst);
413 }
414 }
415 }};
416
417 output decoder {{
418 namespace Aarch64
419 {
420 StaticInstPtr
421 decodeLoadsStores(ExtMachInst machInst)
422 {
423 // bit 27,25=10
424 switch (bits(machInst, 29, 28)) {
425 case 0x0:
426 if (bits(machInst, 26) == 0) {
427 if (bits(machInst, 24) != 0)
428 return new Unknown64(machInst);
429 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
430 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
431 IntRegIndex rnsp = makeSP(rn);
432 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
433 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
434 uint8_t opc = (bits(machInst, 15) << 0) |
435 (bits(machInst, 23, 21) << 1);
436 uint8_t size = bits(machInst, 31, 30);
437 switch (opc) {
438 case 0x0:
439 switch (size) {
440 case 0x0:
441 return new STXRB64(machInst, rt, rnsp, rs);
442 case 0x1:
443 return new STXRH64(machInst, rt, rnsp, rs);
444 case 0x2:
445 return new STXRW64(machInst, rt, rnsp, rs);
446 case 0x3:
447 return new STXRX64(machInst, rt, rnsp, rs);
448 }
449 case 0x1:
450 switch (size) {
451 case 0x0:
452 return new STLXRB64(machInst, rt, rnsp, rs);
453 case 0x1:
454 return new STLXRH64(machInst, rt, rnsp, rs);
455 case 0x2:
456 return new STLXRW64(machInst, rt, rnsp, rs);
457 case 0x3:
458 return new STLXRX64(machInst, rt, rnsp, rs);
459 }
460 case 0x2:
461 switch (size) {
462 case 0x0:
463 case 0x1:
464 return new Unknown64(machInst);
465 case 0x2:
466 return new STXPW64(machInst, rs, rt, rt2, rnsp);
467 case 0x3:
468 return new STXPX64(machInst, rs, rt, rt2, rnsp);
469 }
470
471 case 0x3:
472 switch (size) {
473 case 0x0:
474 case 0x1:
475 return new Unknown64(machInst);
476 case 0x2:
477 return new STLXPW64(machInst, rs, rt, rt2, rnsp);
478 case 0x3:
479 return new STLXPX64(machInst, rs, rt, rt2, rnsp);
480 }
481
482 case 0x4:
483 switch (size) {
484 case 0x0:
485 return new LDXRB64(machInst, rt, rnsp, rs);
486 case 0x1:
487 return new LDXRH64(machInst, rt, rnsp, rs);
488 case 0x2:
489 return new LDXRW64(machInst, rt, rnsp, rs);
490 case 0x3:
491 return new LDXRX64(machInst, rt, rnsp, rs);
492 }
493 case 0x5:
494 switch (size) {
495 case 0x0:
496 return new LDAXRB64(machInst, rt, rnsp, rs);
497 case 0x1:
498 return new LDAXRH64(machInst, rt, rnsp, rs);
499 case 0x2:
500 return new LDAXRW64(machInst, rt, rnsp, rs);
501 case 0x3:
502 return new LDAXRX64(machInst, rt, rnsp, rs);
503 }
504 case 0x6:
505 switch (size) {
506 case 0x0:
507 case 0x1:
508 return new Unknown64(machInst);
509 case 0x2:
510 return new LDXPW64(machInst, rt, rt2, rnsp);
511 case 0x3:
512 return new LDXPX64(machInst, rt, rt2, rnsp);
513 }
514
515 case 0x7:
516 switch (size) {
517 case 0x0:
518 case 0x1:
519 return new Unknown64(machInst);
520 case 0x2:
521 return new LDAXPW64(machInst, rt, rt2, rnsp);
522 case 0x3:
523 return new LDAXPX64(machInst, rt, rt2, rnsp);
524 }
525
526 case 0x9:
527 switch (size) {
528 case 0x0:
529 return new STLRB64(machInst, rt, rnsp);
530 case 0x1:
531 return new STLRH64(machInst, rt, rnsp);
532 case 0x2:
533 return new STLRW64(machInst, rt, rnsp);
534 case 0x3:
535 return new STLRX64(machInst, rt, rnsp);
536 }
537 case 0xd:
538 switch (size) {
539 case 0x0:
540 return new LDARB64(machInst, rt, rnsp);
541 case 0x1:
542 return new LDARH64(machInst, rt, rnsp);
543 case 0x2:
544 return new LDARW64(machInst, rt, rnsp);
545 case 0x3:
546 return new LDARX64(machInst, rt, rnsp);
547 }
548 default:
549 return new Unknown64(machInst);
550 }
551 } else if (bits(machInst, 31)) {
552 return new Unknown64(machInst);
553 } else {
554 return decodeNeonMem(machInst);
555 }
556 case 0x1:
557 {
558 if (bits(machInst, 24) != 0)
559 return new Unknown64(machInst);
560 uint8_t switchVal = (bits(machInst, 26) << 0) |
561 (bits(machInst, 31, 30) << 1);
562 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
563 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
564 switch (switchVal) {
565 case 0x0:
566 return new LDRWL64_LIT(machInst, rt, imm);
567 case 0x1:
568 return new LDRSFP64_LIT(machInst, rt, imm);
569 case 0x2:
570 return new LDRXL64_LIT(machInst, rt, imm);
571 case 0x3:
572 return new LDRDFP64_LIT(machInst, rt, imm);
573 case 0x4:
574 return new LDRSWL64_LIT(machInst, rt, imm);
575 case 0x5:
576 return new BigFpMemLit("ldr", machInst, rt, imm);
577 case 0x6:
578 return new PRFM64_LIT(machInst, rt, imm);
579 default:
580 return new Unknown64(machInst);
581 }
582 }
583 case 0x2:
584 {
585 uint8_t opc = bits(machInst, 31, 30);
586 if (opc >= 3)
587 return new Unknown64(machInst);
588 uint32_t size = 0;
589 bool fp = bits(machInst, 26);
590 bool load = bits(machInst, 22);
591 if (fp) {
592 size = 4 << opc;
593 } else {
594 if ((opc == 1) && !load)
595 return new Unknown64(machInst);
596 size = (opc == 0 || opc == 1) ? 4 : 8;
597 }
598 uint8_t type = bits(machInst, 24, 23);
599 int64_t imm = sext<7>(bits(machInst, 21, 15)) * size;
600
601 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
602 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
603 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
604
605 bool noAlloc = (type == 0);
606 bool signExt = !noAlloc && !fp && opc == 1;
607 PairMemOp::AddrMode mode;
608 const char *mnemonic = NULL;
609 switch (type) {
610 case 0x0:
611 case 0x2:
612 mode = PairMemOp::AddrMd_Offset;
613 break;
614 case 0x1:
615 mode = PairMemOp::AddrMd_PostIndex;
616 break;
617 case 0x3:
618 mode = PairMemOp::AddrMd_PreIndex;
619 break;
620 default:
621 return new Unknown64(machInst);
622 }
623 if (load) {
624 if (noAlloc)
625 mnemonic = "ldnp";
626 else if (signExt)
627 mnemonic = "ldpsw";
628 else
629 mnemonic = "ldp";
630 } else {
631 if (noAlloc)
632 mnemonic = "stnp";
633 else
634 mnemonic = "stp";
635 }
636
637 return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc,
638 signExt, false, false, imm, mode, rn, rt, rt2);
639 }
640 // bit 29:27=111, 25=0
641 case 0x3:
642 {
643 uint8_t switchVal = (bits(machInst, 23, 22) << 0) |
644 (bits(machInst, 26) << 2) |
645 (bits(machInst, 31, 30) << 3);
646 if (bits(machInst, 24) == 1) {
647 uint64_t imm12 = bits(machInst, 21, 10);
648 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
649 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
650 IntRegIndex rnsp = makeSP(rn);
651 switch (switchVal) {
652 case 0x00:
653 return new STRB64_IMM(machInst, rt, rnsp, imm12);
654 case 0x01:
655 return new LDRB64_IMM(machInst, rt, rnsp, imm12);
656 case 0x02:
657 return new LDRSBX64_IMM(machInst, rt, rnsp, imm12);
658 case 0x03:
659 return new LDRSBW64_IMM(machInst, rt, rnsp, imm12);
660 case 0x04:
661 return new STRBFP64_IMM(machInst, rt, rnsp, imm12);
662 case 0x05:
663 return new LDRBFP64_IMM(machInst, rt, rnsp, imm12);
664 case 0x06:
665 return new BigFpMemImm("str", machInst, false,
666 rt, rnsp, imm12 << 4);
667 case 0x07:
668 return new BigFpMemImm("ldr", machInst, true,
669 rt, rnsp, imm12 << 4);
670 case 0x08:
671 return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1);
672 case 0x09:
673 return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1);
674 case 0x0a:
675 return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1);
676 case 0x0b:
677 return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1);
678 case 0x0c:
679 return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
680 case 0x0d:
681 return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
682 case 0x10:
683 return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2);
684 case 0x11:
685 return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2);
686 case 0x12:
687 return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2);
688 case 0x14:
689 return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
690 case 0x15:
691 return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
692 case 0x18:
693 return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3);
694 case 0x19:
695 return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3);
696 case 0x1a:
697 return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3);
698 case 0x1c:
699 return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
700 case 0x1d:
701 return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
702 default:
703 return new Unknown64(machInst);
704 }
705 } else if (bits(machInst, 21) == 1) {
706 if (bits(machInst, 11, 10) != 0x2)
707 return new Unknown64(machInst);
708 if (!bits(machInst, 14))
709 return new Unknown64(machInst);
710 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
711 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
712 IntRegIndex rnsp = makeSP(rn);
713 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
714 ArmExtendType type =
715 (ArmExtendType)(uint32_t)bits(machInst, 15, 13);
716 uint8_t s = bits(machInst, 12);
717 switch (switchVal) {
718 case 0x00:
719 return new STRB64_REG(machInst, rt, rnsp, rm, type, 0);
720 case 0x01:
721 return new LDRB64_REG(machInst, rt, rnsp, rm, type, 0);
722 case 0x02:
723 return new LDRSBX64_REG(machInst, rt, rnsp, rm, type, 0);
724 case 0x03:
725 return new LDRSBW64_REG(machInst, rt, rnsp, rm, type, 0);
726 case 0x04:
727 return new STRBFP64_REG(machInst, rt, rnsp, rm, type, 0);
728 case 0x05:
729 return new LDRBFP64_REG(machInst, rt, rnsp, rm, type, 0);
730 case 0x6:
731 return new BigFpMemReg("str", machInst, false,
732 rt, rnsp, rm, type, s * 4);
733 case 0x7:
734 return new BigFpMemReg("ldr", machInst, true,
735 rt, rnsp, rm, type, s * 4);
736 case 0x08:
737 return new STRH64_REG(machInst, rt, rnsp, rm, type, s);
738 case 0x09:
739 return new LDRH64_REG(machInst, rt, rnsp, rm, type, s);
740 case 0x0a:
741 return new LDRSHX64_REG(machInst, rt, rnsp, rm, type, s);
742 case 0x0b:
743 return new LDRSHW64_REG(machInst, rt, rnsp, rm, type, s);
744 case 0x0c:
745 return new STRHFP64_REG(machInst, rt, rnsp, rm, type, s);
746 case 0x0d:
747 return new LDRHFP64_REG(machInst, rt, rnsp, rm, type, s);
748 case 0x10:
749 return new STRW64_REG(machInst, rt, rnsp, rm, type, s * 2);
750 case 0x11:
751 return new LDRW64_REG(machInst, rt, rnsp, rm, type, s * 2);
752 case 0x12:
753 return new LDRSW64_REG(machInst, rt, rnsp, rm, type, s * 2);
754 case 0x14:
755 return new STRSFP64_REG(machInst, rt, rnsp, rm, type, s * 2);
756 case 0x15:
757 return new LDRSFP64_REG(machInst, rt, rnsp, rm, type, s * 2);
758 case 0x18:
759 return new STRX64_REG(machInst, rt, rnsp, rm, type, s * 3);
760 case 0x19:
761 return new LDRX64_REG(machInst, rt, rnsp, rm, type, s * 3);
762 case 0x1a:
763 return new PRFM64_REG(machInst, rt, rnsp, rm, type, s * 3);
764 case 0x1c:
765 return new STRDFP64_REG(machInst, rt, rnsp, rm, type, s * 3);
766 case 0x1d:
767 return new LDRDFP64_REG(machInst, rt, rnsp, rm, type, s * 3);
768 default:
769 return new Unknown64(machInst);
770 }
771 } else {
772 // bit 29:27=111, 25:24=00, 21=0
773 switch (bits(machInst, 11, 10)) {
774 case 0x0:
775 {
776 IntRegIndex rt =
777 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
778 IntRegIndex rn =
779 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
780 IntRegIndex rnsp = makeSP(rn);
781 uint64_t imm = sext<9>(bits(machInst, 20, 12));
782 switch (switchVal) {
783 case 0x00:
784 return new STURB64_IMM(machInst, rt, rnsp, imm);
785 case 0x01:
786 return new LDURB64_IMM(machInst, rt, rnsp, imm);
787 case 0x02:
788 return new LDURSBX64_IMM(machInst, rt, rnsp, imm);
789 case 0x03:
790 return new LDURSBW64_IMM(machInst, rt, rnsp, imm);
791 case 0x04:
792 return new STURBFP64_IMM(machInst, rt, rnsp, imm);
793 case 0x05:
794 return new LDURBFP64_IMM(machInst, rt, rnsp, imm);
795 case 0x06:
796 return new BigFpMemImm("stur", machInst, false,
797 rt, rnsp, imm);
798 case 0x07:
799 return new BigFpMemImm("ldur", machInst, true,
800 rt, rnsp, imm);
801 case 0x08:
802 return new STURH64_IMM(machInst, rt, rnsp, imm);
803 case 0x09:
804 return new LDURH64_IMM(machInst, rt, rnsp, imm);
805 case 0x0a:
806 return new LDURSHX64_IMM(machInst, rt, rnsp, imm);
807 case 0x0b:
808 return new LDURSHW64_IMM(machInst, rt, rnsp, imm);
809 case 0x0c:
810 return new STURHFP64_IMM(machInst, rt, rnsp, imm);
811 case 0x0d:
812 return new LDURHFP64_IMM(machInst, rt, rnsp, imm);
813 case 0x10:
814 return new STURW64_IMM(machInst, rt, rnsp, imm);
815 case 0x11:
816 return new LDURW64_IMM(machInst, rt, rnsp, imm);
817 case 0x12:
818 return new LDURSW64_IMM(machInst, rt, rnsp, imm);
819 case 0x14:
820 return new STURSFP64_IMM(machInst, rt, rnsp, imm);
821 case 0x15:
822 return new LDURSFP64_IMM(machInst, rt, rnsp, imm);
823 case 0x18:
824 return new STURX64_IMM(machInst, rt, rnsp, imm);
825 case 0x19:
826 return new LDURX64_IMM(machInst, rt, rnsp, imm);
827 case 0x1a:
828 return new PRFUM64_IMM(machInst, rt, rnsp, imm);
829 case 0x1c:
830 return new STURDFP64_IMM(machInst, rt, rnsp, imm);
831 case 0x1d:
832 return new LDURDFP64_IMM(machInst, rt, rnsp, imm);
833 default:
834 return new Unknown64(machInst);
835 }
836 }
837 // bit 29:27=111, 25:24=00, 21=0, 11:10=01
838 case 0x1:
839 {
840 IntRegIndex rt =
841 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
842 IntRegIndex rn =
843 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
844 IntRegIndex rnsp = makeSP(rn);
845 uint64_t imm = sext<9>(bits(machInst, 20, 12));
846 switch (switchVal) {
847 case 0x00:
848 return new STRB64_POST(machInst, rt, rnsp, imm);
849 case 0x01:
850 return new LDRB64_POST(machInst, rt, rnsp, imm);
851 case 0x02:
852 return new LDRSBX64_POST(machInst, rt, rnsp, imm);
853 case 0x03:
854 return new LDRSBW64_POST(machInst, rt, rnsp, imm);
855 case 0x04:
856 return new STRBFP64_POST(machInst, rt, rnsp, imm);
857 case 0x05:
858 return new LDRBFP64_POST(machInst, rt, rnsp, imm);
859 case 0x06:
860 return new BigFpMemPost("str", machInst, false,
861 rt, rnsp, imm);
862 case 0x07:
863 return new BigFpMemPost("ldr", machInst, true,
864 rt, rnsp, imm);
865 case 0x08:
866 return new STRH64_POST(machInst, rt, rnsp, imm);
867 case 0x09:
868 return new LDRH64_POST(machInst, rt, rnsp, imm);
869 case 0x0a:
870 return new LDRSHX64_POST(machInst, rt, rnsp, imm);
871 case 0x0b:
872 return new LDRSHW64_POST(machInst, rt, rnsp, imm);
873 case 0x0c:
874 return new STRHFP64_POST(machInst, rt, rnsp, imm);
875 case 0x0d:
876 return new LDRHFP64_POST(machInst, rt, rnsp, imm);
877 case 0x10:
878 return new STRW64_POST(machInst, rt, rnsp, imm);
879 case 0x11:
880 return new LDRW64_POST(machInst, rt, rnsp, imm);
881 case 0x12:
882 return new LDRSW64_POST(machInst, rt, rnsp, imm);
883 case 0x14:
884 return new STRSFP64_POST(machInst, rt, rnsp, imm);
885 case 0x15:
886 return new LDRSFP64_POST(machInst, rt, rnsp, imm);
887 case 0x18:
888 return new STRX64_POST(machInst, rt, rnsp, imm);
889 case 0x19:
890 return new LDRX64_POST(machInst, rt, rnsp, imm);
891 case 0x1c:
892 return new STRDFP64_POST(machInst, rt, rnsp, imm);
893 case 0x1d:
894 return new LDRDFP64_POST(machInst, rt, rnsp, imm);
895 default:
896 return new Unknown64(machInst);
897 }
898 }
899 case 0x2:
900 {
901 IntRegIndex rt =
902 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
903 IntRegIndex rn =
904 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
905 IntRegIndex rnsp = makeSP(rn);
906 uint64_t imm = sext<9>(bits(machInst, 20, 12));
907 switch (switchVal) {
908 case 0x00:
909 return new STTRB64_IMM(machInst, rt, rnsp, imm);
910 case 0x01:
911 return new LDTRB64_IMM(machInst, rt, rnsp, imm);
912 case 0x02:
913 return new LDTRSBX64_IMM(machInst, rt, rnsp, imm);
914 case 0x03:
915 return new LDTRSBW64_IMM(machInst, rt, rnsp, imm);
916 case 0x08:
917 return new STTRH64_IMM(machInst, rt, rnsp, imm);
918 case 0x09:
919 return new LDTRH64_IMM(machInst, rt, rnsp, imm);
920 case 0x0a:
921 return new LDTRSHX64_IMM(machInst, rt, rnsp, imm);
922 case 0x0b:
923 return new LDTRSHW64_IMM(machInst, rt, rnsp, imm);
924 case 0x10:
925 return new STTRW64_IMM(machInst, rt, rnsp, imm);
926 case 0x11:
927 return new LDTRW64_IMM(machInst, rt, rnsp, imm);
928 case 0x12:
929 return new LDTRSW64_IMM(machInst, rt, rnsp, imm);
930 case 0x18:
931 return new STTRX64_IMM(machInst, rt, rnsp, imm);
932 case 0x19:
933 return new LDTRX64_IMM(machInst, rt, rnsp, imm);
934 default:
935 return new Unknown64(machInst);
936 }
937 }
938 case 0x3:
939 {
940 IntRegIndex rt =
941 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
942 IntRegIndex rn =
943 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
944 IntRegIndex rnsp = makeSP(rn);
945 uint64_t imm = sext<9>(bits(machInst, 20, 12));
946 switch (switchVal) {
947 case 0x00:
948 return new STRB64_PRE(machInst, rt, rnsp, imm);
949 case 0x01:
950 return new LDRB64_PRE(machInst, rt, rnsp, imm);
951 case 0x02:
952 return new LDRSBX64_PRE(machInst, rt, rnsp, imm);
953 case 0x03:
954 return new LDRSBW64_PRE(machInst, rt, rnsp, imm);
955 case 0x04:
956 return new STRBFP64_PRE(machInst, rt, rnsp, imm);
957 case 0x05:
958 return new LDRBFP64_PRE(machInst, rt, rnsp, imm);
959 case 0x06:
960 return new BigFpMemPre("str", machInst, false,
961 rt, rnsp, imm);
962 case 0x07:
963 return new BigFpMemPre("ldr", machInst, true,
964 rt, rnsp, imm);
965 case 0x08:
966 return new STRH64_PRE(machInst, rt, rnsp, imm);
967 case 0x09:
968 return new LDRH64_PRE(machInst, rt, rnsp, imm);
969 case 0x0a:
970 return new LDRSHX64_PRE(machInst, rt, rnsp, imm);
971 case 0x0b:
972 return new LDRSHW64_PRE(machInst, rt, rnsp, imm);
973 case 0x0c:
974 return new STRHFP64_PRE(machInst, rt, rnsp, imm);
975 case 0x0d:
976 return new LDRHFP64_PRE(machInst, rt, rnsp, imm);
977 case 0x10:
978 return new STRW64_PRE(machInst, rt, rnsp, imm);
979 case 0x11:
980 return new LDRW64_PRE(machInst, rt, rnsp, imm);
981 case 0x12:
982 return new LDRSW64_PRE(machInst, rt, rnsp, imm);
983 case 0x14:
984 return new STRSFP64_PRE(machInst, rt, rnsp, imm);
985 case 0x15:
986 return new LDRSFP64_PRE(machInst, rt, rnsp, imm);
987 case 0x18:
988 return new STRX64_PRE(machInst, rt, rnsp, imm);
989 case 0x19:
990 return new LDRX64_PRE(machInst, rt, rnsp, imm);
991 case 0x1c:
992 return new STRDFP64_PRE(machInst, rt, rnsp, imm);
993 case 0x1d:
994 return new LDRDFP64_PRE(machInst, rt, rnsp, imm);
995 default:
996 return new Unknown64(machInst);
997 }
998 }
999 }
1000 }
1001 }
1002 }
1003 return new FailUnimplemented("Unhandled Case1", machInst);
1004 }
1005 }
1006 }};
1007
1008 output decoder {{
1009 namespace Aarch64
1010 {
1011 StaticInstPtr
1012 decodeDataProcReg(ExtMachInst machInst)
1013 {
1014 uint8_t switchVal = (bits(machInst, 28) << 1) |
1015 (bits(machInst, 24) << 0);
1016 switch (switchVal) {
1017 case 0x0:
1018 {
1019 uint8_t switchVal = (bits(machInst, 21) << 0) |
1020 (bits(machInst, 30, 29) << 1);
1021 ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1022 uint8_t imm6 = bits(machInst, 15, 10);
1023 bool sf = bits(machInst, 31);
1024 if (!sf && (imm6 & 0x20))
1025 return new Unknown64(machInst);
1026 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1027 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1028 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1029
1030 switch (switchVal) {
1031 case 0x0:
1032 return new AndXSReg(machInst, rd, rn, rm, imm6, type);
1033 case 0x1:
1034 return new BicXSReg(machInst, rd, rn, rm, imm6, type);
1035 case 0x2:
1036 return new OrrXSReg(machInst, rd, rn, rm, imm6, type);
1037 case 0x3:
1038 return new OrnXSReg(machInst, rd, rn, rm, imm6, type);
1039 case 0x4:
1040 return new EorXSReg(machInst, rd, rn, rm, imm6, type);
1041 case 0x5:
1042 return new EonXSReg(machInst, rd, rn, rm, imm6, type);
1043 case 0x6:
1044 return new AndXSRegCc(machInst, rd, rn, rm, imm6, type);
1045 case 0x7:
1046 return new BicXSRegCc(machInst, rd, rn, rm, imm6, type);
1047 }
1048 }
1049 case 0x1:
1050 {
1051 uint8_t switchVal = bits(machInst, 30, 29);
1052 if (bits(machInst, 21) == 0) {
1053 ArmShiftType type =
1054 (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1055 if (type == ROR)
1056 return new Unknown64(machInst);
1057 uint8_t imm6 = bits(machInst, 15, 10);
1058 if (!bits(machInst, 31) && bits(imm6, 5))
1059 return new Unknown64(machInst);
1060 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1061 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1062 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1063 switch (switchVal) {
1064 case 0x0:
1065 return new AddXSReg(machInst, rd, rn, rm, imm6, type);
1066 case 0x1:
1067 return new AddXSRegCc(machInst, rd, rn, rm, imm6, type);
1068 case 0x2:
1069 return new SubXSReg(machInst, rd, rn, rm, imm6, type);
1070 case 0x3:
1071 return new SubXSRegCc(machInst, rd, rn, rm, imm6, type);
1072 }
1073 } else {
1074 if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4)
1075 return new Unknown64(machInst);
1076 ArmExtendType type =
1077 (ArmExtendType)(uint8_t)bits(machInst, 15, 13);
1078 uint8_t imm3 = bits(machInst, 12, 10);
1079 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1080 IntRegIndex rdsp = makeSP(rd);
1081 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1082 IntRegIndex rnsp = makeSP(rn);
1083 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1084
1085 switch (switchVal) {
1086 case 0x0:
1087 return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1088 case 0x1:
1089 return new AddXERegCc(machInst, rd, rnsp, rm, type, imm3);
1090 case 0x2:
1091 return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1092 case 0x3:
1093 return new SubXERegCc(machInst, rd, rnsp, rm, type, imm3);
1094 }
1095 }
1096 }
1097 case 0x2:
1098 {
1099 if (bits(machInst, 21) == 1)
1100 return new Unknown64(machInst);
1101 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1102 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1103 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1104 switch (bits(machInst, 23, 22)) {
1105 case 0x0:
1106 {
1107 if (bits(machInst, 15, 10))
1108 return new Unknown64(machInst);
1109 uint8_t switchVal = bits(machInst, 30, 29);
1110 switch (switchVal) {
1111 case 0x0:
1112 return new AdcXSReg(machInst, rd, rn, rm, 0, LSL);
1113 case 0x1:
1114 return new AdcXSRegCc(machInst, rd, rn, rm, 0, LSL);
1115 case 0x2:
1116 return new SbcXSReg(machInst, rd, rn, rm, 0, LSL);
1117 case 0x3:
1118 return new SbcXSRegCc(machInst, rd, rn, rm, 0, LSL);
1119 }
1120 }
1121 case 0x1:
1122 {
1123 if ((bits(machInst, 4) == 1) ||
1124 (bits(machInst, 10) == 1) ||
1125 (bits(machInst, 29) == 0)) {
1126 return new Unknown64(machInst);
1127 }
1128 ConditionCode cond =
1129 (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1130 uint8_t flags = bits(machInst, 3, 0);
1131 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1132 if (bits(machInst, 11) == 0) {
1133 IntRegIndex rm =
1134 (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1135 if (bits(machInst, 30) == 0) {
1136 return new CcmnReg64(machInst, rn, rm, cond, flags);
1137 } else {
1138 return new CcmpReg64(machInst, rn, rm, cond, flags);
1139 }
1140 } else {
1141 uint8_t imm5 = bits(machInst, 20, 16);
1142 if (bits(machInst, 30) == 0) {
1143 return new CcmnImm64(machInst, rn, imm5, cond, flags);
1144 } else {
1145 return new CcmpImm64(machInst, rn, imm5, cond, flags);
1146 }
1147 }
1148 }
1149 case 0x2:
1150 {
1151 if (bits(machInst, 29) == 1 ||
1152 bits(machInst, 11) == 1) {
1153 return new Unknown64(machInst);
1154 }
1155 uint8_t switchVal = (bits(machInst, 10) << 0) |
1156 (bits(machInst, 30) << 1);
1157 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1158 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1159 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1160 ConditionCode cond =
1161 (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1162 switch (switchVal) {
1163 case 0x0:
1164 return new Csel64(machInst, rd, rn, rm, cond);
1165 case 0x1:
1166 return new Csinc64(machInst, rd, rn, rm, cond);
1167 case 0x2:
1168 return new Csinv64(machInst, rd, rn, rm, cond);
1169 case 0x3:
1170 return new Csneg64(machInst, rd, rn, rm, cond);
1171 }
1172 }
1173 case 0x3:
1174 if (bits(machInst, 30) == 0) {
1175 if (bits(machInst, 29) != 0)
1176 return new Unknown64(machInst);
1177 uint8_t switchVal = bits(machInst, 15, 10);
1178 switch (switchVal) {
1179 case 0x2:
1180 return new Udiv64(machInst, rd, rn, rm);
1181 case 0x3:
1182 return new Sdiv64(machInst, rd, rn, rm);
1183 case 0x8:
1184 return new Lslv64(machInst, rd, rn, rm);
1185 case 0x9:
1186 return new Lsrv64(machInst, rd, rn, rm);
1187 case 0xa:
1188 return new Asrv64(machInst, rd, rn, rm);
1189 case 0xb:
1190 return new Rorv64(machInst, rd, rn, rm);
1191 default:
1192 return new Unknown64(machInst);
1193 }
1194 } else {
1195 if (bits(machInst, 20, 16) != 0 ||
1196 bits(machInst, 29) != 0) {
1197 return new Unknown64(machInst);
1198 }
1199 uint8_t switchVal = bits(machInst, 15, 10);
1200 switch (switchVal) {
1201 case 0x0:
1202 return new Rbit64(machInst, rd, rn);
1203 case 0x1:
1204 return new Rev1664(machInst, rd, rn);
1205 case 0x2:
1206 if (bits(machInst, 31) == 0)
1207 return new Rev64(machInst, rd, rn);
1208 else
1209 return new Rev3264(machInst, rd, rn);
1210 case 0x3:
1211 if (bits(machInst, 31) != 1)
1212 return new Unknown64(machInst);
1213 return new Rev64(machInst, rd, rn);
1214 case 0x4:
1215 return new Clz64(machInst, rd, rn);
1216 case 0x5:
1217 return new Cls64(machInst, rd, rn);
1218 }
1219 }
1220 }
1221 }
1222 case 0x3:
1223 {
1224 if (bits(machInst, 30, 29) != 0x0 ||
1225 (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0))
1226 return new Unknown64(machInst);
1227 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1228 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1229 IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
1230 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1231 switch (bits(machInst, 23, 21)) {
1232 case 0x0:
1233 if (bits(machInst, 15) == 0)
1234 return new Madd64(machInst, rd, ra, rn, rm);
1235 else
1236 return new Msub64(machInst, rd, ra, rn, rm);
1237 case 0x1:
1238 if (bits(machInst, 15) == 0)
1239 return new Smaddl64(machInst, rd, ra, rn, rm);
1240 else
1241 return new Smsubl64(machInst, rd, ra, rn, rm);
1242 case 0x2:
1243 if (bits(machInst, 15) != 0)
1244 return new Unknown64(machInst);
1245 return new Smulh64(machInst, rd, rn, rm);
1246 case 0x5:
1247 if (bits(machInst, 15) == 0)
1248 return new Umaddl64(machInst, rd, ra, rn, rm);
1249 else
1250 return new Umsubl64(machInst, rd, ra, rn, rm);
1251 case 0x6:
1252 if (bits(machInst, 15) != 0)
1253 return new Unknown64(machInst);
1254 return new Umulh64(machInst, rd, rn, rm);
1255 default:
1256 return new Unknown64(machInst);
1257 }
1258 }
1259 }
1260 return new FailUnimplemented("Unhandled Case2", machInst);
1261 }
1262 }
1263 }};
1264
1265 output decoder {{
1266 namespace Aarch64
1267 {
1268 StaticInstPtr
1269 decodeAdvSIMD(ExtMachInst machInst)
1270 {
1271 if (bits(machInst, 24) == 1) {
1272 if (bits(machInst, 10) == 0) {
1273 return decodeNeonIndexedElem(machInst);
1274 } else if (bits(machInst, 23) == 1) {
1275 return new Unknown64(machInst);
1276 } else {
1277 if (bits(machInst, 22, 19)) {
1278 return decodeNeonShiftByImm(machInst);
1279 } else {
1280 return decodeNeonModImm(machInst);
1281 }
1282 }
1283 } else if (bits(machInst, 21) == 1) {
1284 if (bits(machInst, 10) == 1) {
1285 return decodeNeon3Same(machInst);
1286 } else if (bits(machInst, 11) == 0) {
1287 return decodeNeon3Diff(machInst);
1288 } else if (bits(machInst, 20, 17) == 0x0) {
1289 return decodeNeon2RegMisc(machInst);
1290 } else if (bits(machInst, 20, 17) == 0x8) {
1291 return decodeNeonAcrossLanes(machInst);
1292 } else {
1293 return new Unknown64(machInst);
1294 }
1295 } else if (bits(machInst, 24) ||
1296 bits(machInst, 21) ||
1297 bits(machInst, 15)) {
1298 return new Unknown64(machInst);
1299 } else if (bits(machInst, 10) == 1) {
1300 if (bits(machInst, 23, 22))
1301 return new Unknown64(machInst);
1302 return decodeNeonCopy(machInst);
1303 } else if (bits(machInst, 29) == 1) {
1304 return decodeNeonExt(machInst);
1305 } else if (bits(machInst, 11) == 1) {
1306 return decodeNeonZipUzpTrn(machInst);
1307 } else if (bits(machInst, 23, 22) == 0x0) {
1308 return decodeNeonTblTbx(machInst);
1309 } else {
1310 return new Unknown64(machInst);
1311 }
1312 return new FailUnimplemented("Unhandled Case3", machInst);
1313 }
1314 }
1315 }};
1316
1317
1318 output decoder {{
1319 namespace Aarch64
1320 {
1321 StaticInstPtr
1322 // bit 30=0, 28:25=1111
1323 decodeFp(ExtMachInst machInst)
1324 {
1325 if (bits(machInst, 24) == 1) {
1326 if (bits(machInst, 31) || bits(machInst, 29))
1327 return new Unknown64(machInst);
1328 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1329 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1330 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
1331 IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 14, 10);
1332 uint8_t switchVal = (bits(machInst, 23, 21) << 1) |
1333 (bits(machInst, 15) << 0);
1334 switch (switchVal) {
1335 case 0x0: // FMADD Sd = Sa + Sn*Sm
1336 return new FMAddS(machInst, rd, rn, rm, ra);
1337 case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm
1338 return new FMSubS(machInst, rd, rn, rm, ra);
1339 case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm
1340 return new FNMAddS(machInst, rd, rn, rm, ra);
1341 case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm
1342 return new FNMSubS(machInst, rd, rn, rm, ra);
1343 case 0x4: // FMADD Dd = Da + Dn*Dm
1344 return new FMAddD(machInst, rd, rn, rm, ra);
1345 case 0x5: // FMSUB Dd = Da + (-Dn)*Dm
1346 return new FMSubD(machInst, rd, rn, rm, ra);
1347 case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm
1348 return new FNMAddD(machInst, rd, rn, rm, ra);
1349 case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm
1350 return new FNMSubD(machInst, rd, rn, rm, ra);
1351 default:
1352 return new Unknown64(machInst);
1353 }
1354 } else if (bits(machInst, 21) == 0) {
1355 bool s = bits(machInst, 29);
1356 if (s)
1357 return new Unknown64(machInst);
1358 uint8_t switchVal = bits(machInst, 20, 16);
1359 uint8_t type = bits(machInst, 23, 22);
1360 uint8_t scale = bits(machInst, 15, 10);
1361 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1362 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1363 if (bits(machInst, 18, 17) == 3 && scale != 0)
1364 return new Unknown64(machInst);
1365 // 30:24=0011110, 21=0
1366 switch (switchVal) {
1367 case 0x00:
1368 return new FailUnimplemented("fcvtns", machInst);
1369 case 0x01:
1370 return new FailUnimplemented("fcvtnu", machInst);
1371 case 0x02:
1372 switch ( (bits(machInst, 31) << 2) | type ) {
1373 case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits))
1374 return new FcvtSFixedFpSW(machInst, rd, rn, scale);
1375 case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits))
1376 return new FcvtSFixedFpDW(machInst, rd, rn, scale);
1377 case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits))
1378 return new FcvtSFixedFpSX(machInst, rd, rn, scale);
1379 case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits))
1380 return new FcvtSFixedFpDX(machInst, rd, rn, scale);
1381 default:
1382 return new Unknown64(machInst);
1383 }
1384 case 0x03:
1385 switch ( (bits(machInst, 31) << 2) | type ) {
1386 case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits))
1387 return new FcvtUFixedFpSW(machInst, rd, rn, scale);
1388 case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits))
1389 return new FcvtUFixedFpDW(machInst, rd, rn, scale);
1390 case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits))
1391 return new FcvtUFixedFpSX(machInst, rd, rn, scale);
1392 case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits))
1393 return new FcvtUFixedFpDX(machInst, rd, rn, scale);
1394 default:
1395 return new Unknown64(machInst);
1396 }
1397 case 0x04:
1398 return new FailUnimplemented("fcvtas", machInst);
1399 case 0x05:
1400 return new FailUnimplemented("fcvtau", machInst);
1401 case 0x08:
1402 return new FailUnimplemented("fcvtps", machInst);
1403 case 0x09:
1404 return new FailUnimplemented("fcvtpu", machInst);
1405 case 0x0e:
1406 return new FailUnimplemented("fmov elem. to 64", machInst);
1407 case 0x0f:
1408 return new FailUnimplemented("fmov 64 bit", machInst);
1409 case 0x10:
1410 return new FailUnimplemented("fcvtms", machInst);
1411 case 0x11:
1412 return new FailUnimplemented("fcvtmu", machInst);
1413 case 0x18:
1414 switch ( (bits(machInst, 31) << 2) | type ) {
1415 case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits))
1416 return new FcvtFpSFixedSW(machInst, rd, rn, scale);
1417 case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits))
1418 return new FcvtFpSFixedDW(machInst, rd, rn, scale);
1419 case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits))
1420 return new FcvtFpSFixedSX(machInst, rd, rn, scale);
1421 case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits))
1422 return new FcvtFpSFixedDX(machInst, rd, rn, scale);
1423 default:
1424 return new Unknown64(machInst);
1425 }
1426 case 0x19:
1427 switch ( (bits(machInst, 31) << 2) | type ) {
1428 case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits))
1429 return new FcvtFpUFixedSW(machInst, rd, rn, scale);
1430 case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits))
1431 return new FcvtFpUFixedDW(machInst, rd, rn, scale);
1432 case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits))
1433 return new FcvtFpUFixedSX(machInst, rd, rn, scale);
1434 case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits))
1435 return new FcvtFpUFixedDX(machInst, rd, rn, scale);
1436 default:
1437 return new Unknown64(machInst);
1438 }
1439 }
1440 } else {
1441 // 30=0, 28:24=11110, 21=1
1442 uint8_t type = bits(machInst, 23, 22);
1443 uint8_t imm8 = bits(machInst, 20, 13);
1444 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1445 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1446 switch (bits(machInst, 11, 10)) {
1447 case 0x0:
1448 if (bits(machInst, 12) == 1) {
1449 if (bits(machInst, 31) ||
1450 bits(machInst, 29) ||
1451 bits(machInst, 9, 5)) {
1452 return new Unknown64(machInst);
1453 }
1454 // 31:29=000, 28:24=11110, 21=1, 12:10=100
1455 if (type == 0) {
1456 // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5)
1457 // :imm8<5:0>:Zeros(19)
1458 uint32_t imm = vfp_modified_imm(imm8, false);
1459 return new FmovImmS(machInst, rd, imm);
1460 } else if (type == 1) {
1461 // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8)
1462 // :imm8<5:0>:Zeros(48)
1463 uint64_t imm = vfp_modified_imm(imm8, true);
1464 return new FmovImmD(machInst, rd, imm);
1465 } else {
1466 return new Unknown64(machInst);
1467 }
1468 } else if (bits(machInst, 13) == 1) {
1469 if (bits(machInst, 31) ||
1470 bits(machInst, 29) ||
1471 bits(machInst, 15, 14) ||
1472 bits(machInst, 23) ||
1473 bits(machInst, 2, 0)) {
1474 return new Unknown64(machInst);
1475 }
1476 uint8_t switchVal = (bits(machInst, 4, 3) << 0) |
1477 (bits(machInst, 22) << 2);
1478 IntRegIndex rm = (IntRegIndex)(uint32_t)
1479 bits(machInst, 20, 16);
1480 // 28:23=000111100, 21=1, 15:10=001000, 2:0=000
1481 switch (switchVal) {
1482 case 0x0:
1483 // FCMP flags = compareQuiet(Sn,Sm)
1484 return new FCmpRegS(machInst, rn, rm);
1485 case 0x1:
1486 // FCMP flags = compareQuiet(Sn,0.0)
1487 return new FCmpImmS(machInst, rn, 0);
1488 case 0x2:
1489 // FCMPE flags = compareSignaling(Sn,Sm)
1490 return new FCmpERegS(machInst, rn, rm);
1491 case 0x3:
1492 // FCMPE flags = compareSignaling(Sn,0.0)
1493 return new FCmpEImmS(machInst, rn, 0);
1494 case 0x4:
1495 // FCMP flags = compareQuiet(Dn,Dm)
1496 return new FCmpRegD(machInst, rn, rm);
1497 case 0x5:
1498 // FCMP flags = compareQuiet(Dn,0.0)
1499 return new FCmpImmD(machInst, rn, 0);
1500 case 0x6:
1501 // FCMPE flags = compareSignaling(Dn,Dm)
1502 return new FCmpERegD(machInst, rn, rm);
1503 case 0x7:
1504 // FCMPE flags = compareSignaling(Dn,0.0)
1505 return new FCmpEImmD(machInst, rn, 0);
1506 default:
1507 return new Unknown64(machInst);
1508 }
1509 } else if (bits(machInst, 14) == 1) {
1510 if (bits(machInst, 31) || bits(machInst, 29))
1511 return new Unknown64(machInst);
1512 uint8_t opcode = bits(machInst, 20, 15);
1513 // Bits 31:24=00011110, 21=1, 14:10=10000
1514 switch (opcode) {
1515 case 0x0:
1516 if (type == 0)
1517 // FMOV Sd = Sn
1518 return new FmovRegS(machInst, rd, rn);
1519 else if (type == 1)
1520 // FMOV Dd = Dn
1521 return new FmovRegD(machInst, rd, rn);
1522 break;
1523 case 0x1:
1524 if (type == 0)
1525 // FABS Sd = abs(Sn)
1526 return new FAbsS(machInst, rd, rn);
1527 else if (type == 1)
1528 // FABS Dd = abs(Dn)
1529 return new FAbsD(machInst, rd, rn);
1530 break;
1531 case 0x2:
1532 if (type == 0)
1533 // FNEG Sd = -Sn
1534 return new FNegS(machInst, rd, rn);
1535 else if (type == 1)
1536 // FNEG Dd = -Dn
1537 return new FNegD(machInst, rd, rn);
1538 break;
1539 case 0x3:
1540 if (type == 0)
1541 // FSQRT Sd = sqrt(Sn)
1542 return new FSqrtS(machInst, rd, rn);
1543 else if (type == 1)
1544 // FSQRT Dd = sqrt(Dn)
1545 return new FSqrtD(machInst, rd, rn);
1546 break;
1547 case 0x4:
1548 if (type == 1)
1549 // FCVT Sd = convertFormat(Dn)
1550 return new FcvtFpDFpS(machInst, rd, rn);
1551 else if (type == 3)
1552 // FCVT Sd = convertFormat(Hn)
1553 return new FcvtFpHFpS(machInst, rd, rn);
1554 break;
1555 case 0x5:
1556 if (type == 0)
1557 // FCVT Dd = convertFormat(Sn)
1558 return new FCvtFpSFpD(machInst, rd, rn);
1559 else if (type == 3)
1560 // FCVT Dd = convertFormat(Hn)
1561 return new FcvtFpHFpD(machInst, rd, rn);
1562 break;
1563 case 0x7:
1564 if (type == 0)
1565 // FCVT Hd = convertFormat(Sn)
1566 return new FcvtFpSFpH(machInst, rd, rn);
1567 else if (type == 1)
1568 // FCVT Hd = convertFormat(Dn)
1569 return new FcvtFpDFpH(machInst, rd, rn);
1570 break;
1571 case 0x8:
1572 if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn)
1573 return new FRIntNS(machInst, rd, rn);
1574 else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn)
1575 return new FRIntND(machInst, rd, rn);
1576 break;
1577 case 0x9:
1578 if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn)
1579 return new FRIntPS(machInst, rd, rn);
1580 else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn)
1581 return new FRIntPD(machInst, rd, rn);
1582 break;
1583 case 0xa:
1584 if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn)
1585 return new FRIntMS(machInst, rd, rn);
1586 else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn)
1587 return new FRIntMD(machInst, rd, rn);
1588 break;
1589 case 0xb:
1590 if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn)
1591 return new FRIntZS(machInst, rd, rn);
1592 else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn)
1593 return new FRIntZD(machInst, rd, rn);
1594 break;
1595 case 0xc:
1596 if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn)
1597 return new FRIntAS(machInst, rd, rn);
1598 else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn)
1599 return new FRIntAD(machInst, rd, rn);
1600 break;
1601 case 0xe:
1602 if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn)
1603 return new FRIntXS(machInst, rd, rn);
1604 else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn)
1605 return new FRIntXD(machInst, rd, rn);
1606 break;
1607 case 0xf:
1608 if (type == 0) // FRINTI Sd = roundToIntegral(Sn)
1609 return new FRIntIS(machInst, rd, rn);
1610 else if (type == 1) // FRINTI Dd = roundToIntegral(Dn)
1611 return new FRIntID(machInst, rd, rn);
1612 break;
1613 default:
1614 return new Unknown64(machInst);
1615 }
1616 return new Unknown64(machInst);
1617 } else if (bits(machInst, 15) == 1) {
1618 return new Unknown64(machInst);
1619 } else {
1620 if (bits(machInst, 29))
1621 return new Unknown64(machInst);
1622 uint8_t rmode = bits(machInst, 20, 19);
1623 uint8_t switchVal1 = bits(machInst, 18, 16);
1624 uint8_t switchVal2 = (type << 1) | bits(machInst, 31);
1625 // 30:24=0011110, 21=1, 15:10=000000
1626 switch (switchVal1) {
1627 case 0x0:
1628 switch ((switchVal2 << 2) | rmode) {
1629 case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn)
1630 return new FcvtFpSIntWSN(machInst, rd, rn);
1631 case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn)
1632 return new FcvtFpSIntWSP(machInst, rd, rn);
1633 case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn)
1634 return new FcvtFpSIntWSM(machInst, rd, rn);
1635 case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn)
1636 return new FcvtFpSIntWSZ(machInst, rd, rn);
1637 case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn)
1638 return new FcvtFpSIntXSN(machInst, rd, rn);
1639 case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn)
1640 return new FcvtFpSIntXSP(machInst, rd, rn);
1641 case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn)
1642 return new FcvtFpSIntXSM(machInst, rd, rn);
1643 case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn)
1644 return new FcvtFpSIntXSZ(machInst, rd, rn);
1645 case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn)
1646 return new FcvtFpSIntWDN(machInst, rd, rn);
1647 case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn)
1648 return new FcvtFpSIntWDP(machInst, rd, rn);
1649 case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn)
1650 return new FcvtFpSIntWDM(machInst, rd, rn);
1651 case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn)
1652 return new FcvtFpSIntWDZ(machInst, rd, rn);
1653 case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn)
1654 return new FcvtFpSIntXDN(machInst, rd, rn);
1655 case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn)
1656 return new FcvtFpSIntXDP(machInst, rd, rn);
1657 case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn)
1658 return new FcvtFpSIntXDM(machInst, rd, rn);
1659 case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn)
1660 return new FcvtFpSIntXDZ(machInst, rd, rn);
1661 default:
1662 return new Unknown64(machInst);
1663 }
1664 case 0x1:
1665 switch ((switchVal2 << 2) | rmode) {
1666 case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn)
1667 return new FcvtFpUIntWSN(machInst, rd, rn);
1668 case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn)
1669 return new FcvtFpUIntWSP(machInst, rd, rn);
1670 case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn)
1671 return new FcvtFpUIntWSM(machInst, rd, rn);
1672 case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn)
1673 return new FcvtFpUIntWSZ(machInst, rd, rn);
1674 case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn)
1675 return new FcvtFpUIntXSN(machInst, rd, rn);
1676 case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn)
1677 return new FcvtFpUIntXSP(machInst, rd, rn);
1678 case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn)
1679 return new FcvtFpUIntXSM(machInst, rd, rn);
1680 case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn)
1681 return new FcvtFpUIntXSZ(machInst, rd, rn);
1682 case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn)
1683 return new FcvtFpUIntWDN(machInst, rd, rn);
1684 case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn)
1685 return new FcvtFpUIntWDP(machInst, rd, rn);
1686 case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn)
1687 return new FcvtFpUIntWDM(machInst, rd, rn);
1688 case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn)
1689 return new FcvtFpUIntWDZ(machInst, rd, rn);
1690 case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn)
1691 return new FcvtFpUIntXDN(machInst, rd, rn);
1692 case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn)
1693 return new FcvtFpUIntXDP(machInst, rd, rn);
1694 case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn)
1695 return new FcvtFpUIntXDM(machInst, rd, rn);
1696 case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn)
1697 return new FcvtFpUIntXDZ(machInst, rd, rn);
1698 default:
1699 return new Unknown64(machInst);
1700 }
1701 case 0x2:
1702 if (rmode != 0)
1703 return new Unknown64(machInst);
1704 switch (switchVal2) {
1705 case 0: // SCVTF Sd = convertFromInt(Wn)
1706 return new FcvtWSIntFpS(machInst, rd, rn);
1707 case 1: // SCVTF Sd = convertFromInt(Xn)
1708 return new FcvtXSIntFpS(machInst, rd, rn);
1709 case 2: // SCVTF Dd = convertFromInt(Wn)
1710 return new FcvtWSIntFpD(machInst, rd, rn);
1711 case 3: // SCVTF Dd = convertFromInt(Xn)
1712 return new FcvtXSIntFpD(machInst, rd, rn);
1713 default:
1714 return new Unknown64(machInst);
1715 }
1716 case 0x3:
1717 switch (switchVal2) {
1718 case 0: // UCVTF Sd = convertFromInt(Wn)
1719 return new FcvtWUIntFpS(machInst, rd, rn);
1720 case 1: // UCVTF Sd = convertFromInt(Xn)
1721 return new FcvtXUIntFpS(machInst, rd, rn);
1722 case 2: // UCVTF Dd = convertFromInt(Wn)
1723 return new FcvtWUIntFpD(machInst, rd, rn);
1724 case 3: // UCVTF Dd = convertFromInt(Xn)
1725 return new FcvtXUIntFpD(machInst, rd, rn);
1726 default:
1727 return new Unknown64(machInst);
1728 }
1729 case 0x4:
1730 if (rmode != 0)
1731 return new Unknown64(machInst);
1732 switch (switchVal2) {
1733 case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn)
1734 return new FcvtFpSIntWSA(machInst, rd, rn);
1735 case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn)
1736 return new FcvtFpSIntXSA(machInst, rd, rn);
1737 case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
1738 return new FcvtFpSIntWDA(machInst, rd, rn);
1739 case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
1740 return new FcvtFpSIntXDA(machInst, rd, rn);
1741 default:
1742 return new Unknown64(machInst);
1743 }
1744 case 0x5:
1745 switch (switchVal2) {
1746 case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn)
1747 return new FcvtFpUIntWSA(machInst, rd, rn);
1748 case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn)
1749 return new FcvtFpUIntXSA(machInst, rd, rn);
1750 case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn)
1751 return new FcvtFpUIntWDA(machInst, rd, rn);
1752 case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn)
1753 return new FcvtFpUIntXDA(machInst, rd, rn);
1754 default:
1755 return new Unknown64(machInst);
1756 }
1757 case 0x06:
1758 switch (switchVal2) {
1759 case 0: // FMOV Wd = Sn
1760 if (rmode != 0)
1761 return new Unknown64(machInst);
1762 return new FmovRegCoreW(machInst, rd, rn);
1763 case 3: // FMOV Xd = Dn
1764 if (rmode != 0)
1765 return new Unknown64(machInst);
1766 return new FmovRegCoreX(machInst, rd, rn);
1767 case 5: // FMOV Xd = Vn<127:64>
1768 if (rmode != 1)
1769 return new Unknown64(machInst);
1770 return new FmovURegCoreX(machInst, rd, rn);
1771 default:
1772 return new Unknown64(machInst);
1773 }
1774 break;
1775 case 0x07:
1776 switch (switchVal2) {
1777 case 0: // FMOV Sd = Wn
1778 if (rmode != 0)
1779 return new Unknown64(machInst);
1780 return new FmovCoreRegW(machInst, rd, rn);
1781 case 3: // FMOV Xd = Dn
1782 if (rmode != 0)
1783 return new Unknown64(machInst);
1784 return new FmovCoreRegX(machInst, rd, rn);
1785 case 5: // FMOV Xd = Vn<127:64>
1786 if (rmode != 1)
1787 return new Unknown64(machInst);
1788 return new FmovUCoreRegX(machInst, rd, rn);
1789 default:
1790 return new Unknown64(machInst);
1791 }
1792 break;
1793 default: // Warning! missing cases in switch statement above, that still need to be added
1794 return new Unknown64(machInst);
1795 }
1796 }
1797 case 0x1:
1798 {
1799 if (bits(machInst, 31) ||
1800 bits(machInst, 29) ||
1801 bits(machInst, 23)) {
1802 return new Unknown64(machInst);
1803 }
1804 IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16);
1805 IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5);
1806 uint8_t imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0);
1807 ConditionCode cond =
1808 (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
1809 uint8_t switchVal = (bits(machInst, 4) << 0) |
1810 (bits(machInst, 22) << 1);
1811 // 31:23=000111100, 21=1, 11:10=01
1812 switch (switchVal) {
1813 case 0x0:
1814 // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv
1815 return new FCCmpRegS(machInst, rn, rm, cond, imm);
1816 case 0x1:
1817 // FCCMP flags = if cond then compareSignaling(Sn,Sm)
1818 // else #nzcv
1819 return new FCCmpERegS(machInst, rn, rm, cond, imm);
1820 case 0x2:
1821 // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv
1822 return new FCCmpRegD(machInst, rn, rm, cond, imm);
1823 case 0x3:
1824 // FCCMP flags = if cond then compareSignaling(Dn,Dm)
1825 // else #nzcv
1826 return new FCCmpERegD(machInst, rn, rm, cond, imm);
1827 default:
1828 return new Unknown64(machInst);
1829 }
1830 }
1831 case 0x2:
1832 {
1833 if (bits(machInst, 31) ||
1834 bits(machInst, 29) ||
1835 bits(machInst, 23)) {
1836 return new Unknown64(machInst);
1837 }
1838 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1839 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1840 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
1841 uint8_t switchVal = (bits(machInst, 15, 12) << 0) |
1842 (bits(machInst, 22) << 4);
1843 switch (switchVal) {
1844 case 0x00: // FMUL Sd = Sn * Sm
1845 return new FMulS(machInst, rd, rn, rm);
1846 case 0x10: // FMUL Dd = Dn * Dm
1847 return new FMulD(machInst, rd, rn, rm);
1848 case 0x01: // FDIV Sd = Sn / Sm
1849 return new FDivS(machInst, rd, rn, rm);
1850 case 0x11: // FDIV Dd = Dn / Dm
1851 return new FDivD(machInst, rd, rn, rm);
1852 case 0x02: // FADD Sd = Sn + Sm
1853 return new FAddS(machInst, rd, rn, rm);
1854 case 0x12: // FADD Dd = Dn + Dm
1855 return new FAddD(machInst, rd, rn, rm);
1856 case 0x03: // FSUB Sd = Sn - Sm
1857 return new FSubS(machInst, rd, rn, rm);
1858 case 0x13: // FSUB Dd = Dn - Dm
1859 return new FSubD(machInst, rd, rn, rm);
1860 case 0x04: // FMAX Sd = max(Sn, Sm)
1861 return new FMaxS(machInst, rd, rn, rm);
1862 case 0x14: // FMAX Dd = max(Dn, Dm)
1863 return new FMaxD(machInst, rd, rn, rm);
1864 case 0x05: // FMIN Sd = min(Sn, Sm)
1865 return new FMinS(machInst, rd, rn, rm);
1866 case 0x15: // FMIN Dd = min(Dn, Dm)
1867 return new FMinD(machInst, rd, rn, rm);
1868 case 0x06: // FMAXNM Sd = maxNum(Sn, Sm)
1869 return new FMaxNMS(machInst, rd, rn, rm);
1870 case 0x16: // FMAXNM Dd = maxNum(Dn, Dm)
1871 return new FMaxNMD(machInst, rd, rn, rm);
1872 case 0x07: // FMINNM Sd = minNum(Sn, Sm)
1873 return new FMinNMS(machInst, rd, rn, rm);
1874 case 0x17: // FMINNM Dd = minNum(Dn, Dm)
1875 return new FMinNMD(machInst, rd, rn, rm);
1876 case 0x08: // FNMUL Sd = -(Sn * Sm)
1877 return new FNMulS(machInst, rd, rn, rm);
1878 case 0x18: // FNMUL Dd = -(Dn * Dm)
1879 return new FNMulD(machInst, rd, rn, rm);
1880 default:
1881 return new Unknown64(machInst);
1882 }
1883 }
1884 case 0x3:
1885 {
1886 if (bits(machInst, 31) || bits(machInst, 29))
1887 return new Unknown64(machInst);
1888 uint8_t type = bits(machInst, 23, 22);
1889 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1890 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1891 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
1892 ConditionCode cond =
1893 (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
1894 if (type == 0) // FCSEL Sd = if cond then Sn else Sm
1895 return new FCSelS(machInst, rd, rn, rm, cond);
1896 else if (type == 1) // FCSEL Dd = if cond then Dn else Dm
1897 return new FCSelD(machInst, rd, rn, rm, cond);
1898 else
1899 return new Unknown64(machInst);
1900 }
1901 }
1902 }
1903 return new FailUnimplemented("Unhandled Case4", machInst);
1904 }
1905 }
1906 }};
1907
1908 output decoder {{
1909 namespace Aarch64
1910 {
1911 StaticInstPtr
1912 decodeAdvSIMDScalar(ExtMachInst machInst)
1913 {
1914 if (bits(machInst, 24) == 1) {
1915 if (bits(machInst, 10) == 0) {
1916 return decodeNeonScIndexedElem(machInst);
1917 } else if (bits(machInst, 23) == 0) {
1918 return decodeNeonScShiftByImm(machInst);
1919 }
1920 } else if (bits(machInst, 21) == 1) {
1921 if (bits(machInst, 10) == 1) {
1922 return decodeNeonSc3Same(machInst);
1923 } else if (bits(machInst, 11) == 0) {
1924 return decodeNeonSc3Diff(machInst);
1925 } else if (bits(machInst, 20, 17) == 0x0) {
1926 return decodeNeonSc2RegMisc(machInst);
1927 } else if (bits(machInst, 20, 17) == 0x8) {
1928 return decodeNeonScPwise(machInst);
1929 } else {
1930 return new Unknown64(machInst);
1931 }
1932 } else if (bits(machInst, 23, 22) == 0 &&
1933 bits(machInst, 15) == 0 &&
1934 bits(machInst, 10) == 1) {
1935 return decodeNeonScCopy(machInst);
1936 } else {
1937 return new Unknown64(machInst);
1938 }
1939 return new FailUnimplemented("Unhandled Case6", machInst);
1940 }
1941 }
1942 }};
1943
1944 output decoder {{
1945 namespace Aarch64
1946 {
1947 StaticInstPtr
1948 decodeFpAdvSIMD(ExtMachInst machInst)
1949 {
1950
1951 if (bits(machInst, 28) == 0) {
1952 if (bits(machInst, 31) == 0) {
1953 return decodeAdvSIMD(machInst);
1954 } else {
1955 return new Unknown64(machInst);
1956 }
1957 } else if (bits(machInst, 30) == 0) {
1958 return decodeFp(machInst);
1959 } else if (bits(machInst, 31) == 0) {
1960 return decodeAdvSIMDScalar(machInst);
1961 } else {
1962 return new Unknown64(machInst);
1963 }
1964 }
1965 }
1966 }};
1967
1968 output decoder {{
1969 namespace Aarch64
1970 {
1971 StaticInstPtr
1972 decodeGem5Ops(ExtMachInst machInst)
1973 {
1974 const uint32_t m5func = bits(machInst, 23, 16);
1975 switch (m5func) {
1976 case 0x00: return new Arm(machInst);
1977 case 0x01: return new Quiesce(machInst);
1978 case 0x02: return new QuiesceNs64(machInst);
1979 case 0x03: return new QuiesceCycles64(machInst);
1980 case 0x04: return new QuiesceTime64(machInst);
1981 case 0x07: return new Rpns64(machInst);
1982 case 0x09: return new WakeCPU64(machInst);
1983 case 0x10: return new Deprecated_ivlb(machInst);
1984 case 0x11: return new Deprecated_ivle(machInst);
1985 case 0x20: return new Deprecated_exit (machInst);
1986 case 0x21: return new M5exit64(machInst);
1987 case 0x31: return new Loadsymbol(machInst);
1988 case 0x30: return new Initparam64(machInst);
1989 case 0x40: return new Resetstats64(machInst);
1990 case 0x41: return new Dumpstats64(machInst);
1991 case 0x42: return new Dumpresetstats64(machInst);
1992 case 0x43: return new M5checkpoint64(machInst);
1993 case 0x4F: return new M5writefile64(machInst);
1994 case 0x50: return new M5readfile64(machInst);
1995 case 0x51: return new M5break(machInst);
1996 case 0x52: return new M5switchcpu(machInst);
1997 case 0x53: return new M5addsymbol64(machInst);
1998 case 0x54: return new M5panic(machInst);
1999 case 0x5a: return new M5workbegin64(machInst);
2000 case 0x5b: return new M5workend64(machInst);
2001 default: return new Unknown64(machInst);
2002 }
2003 }
2004 }
2005 }};
2006
2007 def format Aarch64() {{
2008 decode_block = '''
2009 {
2010 using namespace Aarch64;
2011 if (bits(machInst, 27) == 0x0) {
2012 if (bits(machInst, 28) == 0x0)
2013 return new Unknown64(machInst);
2014 else if (bits(machInst, 26) == 0)
2015 // bit 28:26=100
2016 return decodeDataProcImm(machInst);
2017 else
2018 // bit 28:26=101
2019 return decodeBranchExcSys(machInst);
2020 } else if (bits(machInst, 25) == 0) {
2021 // bit 27=1, 25=0
2022 return decodeLoadsStores(machInst);
2023 } else if (bits(machInst, 26) == 0) {
2024 // bit 27:25=101
2025 return decodeDataProcReg(machInst);
2026 } else if (bits(machInst, 24) == 1 &&
2027 bits(machInst, 31, 28) == 0xF) {
2028 return decodeGem5Ops(machInst);
2029 } else {
2030 // bit 27:25=111
2031 return decodeFpAdvSIMD(machInst);
2032 }
2033 }
2034 '''
2035 }};