Deleted Added
sdiff udiff text old ( 10037:5cac77888310 ) new ( 10173:a6402a046e36 )
full compact
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
41output header {{
42namespace 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
58output decoder {{
59namespace 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
195output decoder {{
196namespace 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(read ? "mrs" : "msr",
378 machInst,
379 csprintf("%s %s",
380 read ? "mrs" : "msr",
381 miscRegName[miscReg]));
382 }
383 }
384 break;
385 }
386 } else if (bits(machInst, 25) == 0x1) {
387 uint8_t opc = bits(machInst, 24, 21);
388 uint8_t op2 = bits(machInst, 20, 16);
389 uint8_t op3 = bits(machInst, 15, 10);
390 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
391 uint8_t op4 = bits(machInst, 4, 0);
392 if (op2 != 0x1f || op3 != 0x0 || op4 != 0x0)
393 return new Unknown64(machInst);
394 switch (opc) {
395 case 0x0:
396 return new Br64(machInst, rn);
397 case 0x1:
398 return new Blr64(machInst, rn);
399 case 0x2:
400 return new Ret64(machInst, rn);
401 case 0x4:
402 if (rn != 0x1f)
403 return new Unknown64(machInst);
404 return new Eret64(machInst);
405 case 0x5:
406 if (rn != 0x1f)
407 return new Unknown64(machInst);
408 return new FailUnimplemented("dret", machInst);
409 }
410 }
411 default:
412 return new Unknown64(machInst);
413 }
414 return new FailUnimplemented("Unhandled Case7", machInst);
415 }
416}
417}};
418
419output decoder {{
420namespace Aarch64
421{
422 StaticInstPtr
423 decodeLoadsStores(ExtMachInst machInst)
424 {
425 // bit 27,25=10
426 switch (bits(machInst, 29, 28)) {
427 case 0x0:
428 if (bits(machInst, 26) == 0) {
429 if (bits(machInst, 24) != 0)
430 return new Unknown64(machInst);
431 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
432 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
433 IntRegIndex rnsp = makeSP(rn);
434 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
435 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
436 uint8_t opc = (bits(machInst, 15) << 0) |
437 (bits(machInst, 23, 21) << 1);
438 uint8_t size = bits(machInst, 31, 30);
439 switch (opc) {
440 case 0x0:
441 switch (size) {
442 case 0x0:
443 return new STXRB64(machInst, rt, rnsp, rs);
444 case 0x1:
445 return new STXRH64(machInst, rt, rnsp, rs);
446 case 0x2:
447 return new STXRW64(machInst, rt, rnsp, rs);
448 case 0x3:
449 return new STXRX64(machInst, rt, rnsp, rs);
450 }
451 case 0x1:
452 switch (size) {
453 case 0x0:
454 return new STLXRB64(machInst, rt, rnsp, rs);
455 case 0x1:
456 return new STLXRH64(machInst, rt, rnsp, rs);
457 case 0x2:
458 return new STLXRW64(machInst, rt, rnsp, rs);
459 case 0x3:
460 return new STLXRX64(machInst, rt, rnsp, rs);
461 }
462 case 0x2:
463 switch (size) {
464 case 0x0:
465 case 0x1:
466 return new Unknown64(machInst);
467 case 0x2:
468 return new STXPW64(machInst, rs, rt, rt2, rnsp);
469 case 0x3:
470 return new STXPX64(machInst, rs, rt, rt2, rnsp);
471 }
472
473 case 0x3:
474 switch (size) {
475 case 0x0:
476 case 0x1:
477 return new Unknown64(machInst);
478 case 0x2:
479 return new STLXPW64(machInst, rs, rt, rt2, rnsp);
480 case 0x3:
481 return new STLXPX64(machInst, rs, rt, rt2, rnsp);
482 }
483
484 case 0x4:
485 switch (size) {
486 case 0x0:
487 return new LDXRB64(machInst, rt, rnsp, rs);
488 case 0x1:
489 return new LDXRH64(machInst, rt, rnsp, rs);
490 case 0x2:
491 return new LDXRW64(machInst, rt, rnsp, rs);
492 case 0x3:
493 return new LDXRX64(machInst, rt, rnsp, rs);
494 }
495 case 0x5:
496 switch (size) {
497 case 0x0:
498 return new LDAXRB64(machInst, rt, rnsp, rs);
499 case 0x1:
500 return new LDAXRH64(machInst, rt, rnsp, rs);
501 case 0x2:
502 return new LDAXRW64(machInst, rt, rnsp, rs);
503 case 0x3:
504 return new LDAXRX64(machInst, rt, rnsp, rs);
505 }
506 case 0x6:
507 switch (size) {
508 case 0x0:
509 case 0x1:
510 return new Unknown64(machInst);
511 case 0x2:
512 return new LDXPW64(machInst, rt, rt2, rnsp);
513 case 0x3:
514 return new LDXPX64(machInst, rt, rt2, rnsp);
515 }
516
517 case 0x7:
518 switch (size) {
519 case 0x0:
520 case 0x1:
521 return new Unknown64(machInst);
522 case 0x2:
523 return new LDAXPW64(machInst, rt, rt2, rnsp);
524 case 0x3:
525 return new LDAXPX64(machInst, rt, rt2, rnsp);
526 }
527
528 case 0x9:
529 switch (size) {
530 case 0x0:
531 return new STLRB64(machInst, rt, rnsp);
532 case 0x1:
533 return new STLRH64(machInst, rt, rnsp);
534 case 0x2:
535 return new STLRW64(machInst, rt, rnsp);
536 case 0x3:
537 return new STLRX64(machInst, rt, rnsp);
538 }
539 case 0xd:
540 switch (size) {
541 case 0x0:
542 return new LDARB64(machInst, rt, rnsp);
543 case 0x1:
544 return new LDARH64(machInst, rt, rnsp);
545 case 0x2:
546 return new LDARW64(machInst, rt, rnsp);
547 case 0x3:
548 return new LDARX64(machInst, rt, rnsp);
549 }
550 default:
551 return new Unknown64(machInst);
552 }
553 } else if (bits(machInst, 31)) {
554 return new Unknown64(machInst);
555 } else {
556 return decodeNeonMem(machInst);
557 }
558 case 0x1:
559 {
560 if (bits(machInst, 24) != 0)
561 return new Unknown64(machInst);
562 uint8_t switchVal = (bits(machInst, 26) << 0) |
563 (bits(machInst, 31, 30) << 1);
564 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
565 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
566 switch (switchVal) {
567 case 0x0:
568 return new LDRWL64_LIT(machInst, rt, imm);
569 case 0x1:
570 return new LDRSFP64_LIT(machInst, rt, imm);
571 case 0x2:
572 return new LDRXL64_LIT(machInst, rt, imm);
573 case 0x3:
574 return new LDRDFP64_LIT(machInst, rt, imm);
575 case 0x4:
576 return new LDRSWL64_LIT(machInst, rt, imm);
577 case 0x5:
578 return new BigFpMemLit("ldr", machInst, rt, imm);
579 case 0x6:
580 return new PRFM64_LIT(machInst, rt, imm);
581 default:
582 return new Unknown64(machInst);
583 }
584 }
585 case 0x2:
586 {
587 uint8_t opc = bits(machInst, 31, 30);
588 if (opc >= 3)
589 return new Unknown64(machInst);
590 uint32_t size = 0;
591 bool fp = bits(machInst, 26);
592 bool load = bits(machInst, 22);
593 if (fp) {
594 size = 4 << opc;
595 } else {
596 if ((opc == 1) && !load)
597 return new Unknown64(machInst);
598 size = (opc == 0 || opc == 1) ? 4 : 8;
599 }
600 uint8_t type = bits(machInst, 24, 23);
601 int64_t imm = sext<7>(bits(machInst, 21, 15)) * size;
602
603 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
604 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
605 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
606
607 bool noAlloc = (type == 0);
608 bool signExt = !noAlloc && !fp && opc == 1;
609 PairMemOp::AddrMode mode;
610 const char *mnemonic = NULL;
611 switch (type) {
612 case 0x0:
613 case 0x2:
614 mode = PairMemOp::AddrMd_Offset;
615 break;
616 case 0x1:
617 mode = PairMemOp::AddrMd_PostIndex;
618 break;
619 case 0x3:
620 mode = PairMemOp::AddrMd_PreIndex;
621 break;
622 default:
623 return new Unknown64(machInst);
624 }
625 if (load) {
626 if (noAlloc)
627 mnemonic = "ldnp";
628 else if (signExt)
629 mnemonic = "ldpsw";
630 else
631 mnemonic = "ldp";
632 } else {
633 if (noAlloc)
634 mnemonic = "stnp";
635 else
636 mnemonic = "stp";
637 }
638
639 return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc,
640 signExt, false, false, imm, mode, rn, rt, rt2);
641 }
642 // bit 29:27=111, 25=0
643 case 0x3:
644 {
645 uint8_t switchVal = (bits(machInst, 23, 22) << 0) |
646 (bits(machInst, 26) << 2) |
647 (bits(machInst, 31, 30) << 3);
648 if (bits(machInst, 24) == 1) {
649 uint64_t imm12 = bits(machInst, 21, 10);
650 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
651 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
652 IntRegIndex rnsp = makeSP(rn);
653 switch (switchVal) {
654 case 0x00:
655 return new STRB64_IMM(machInst, rt, rnsp, imm12);
656 case 0x01:
657 return new LDRB64_IMM(machInst, rt, rnsp, imm12);
658 case 0x02:
659 return new LDRSBX64_IMM(machInst, rt, rnsp, imm12);
660 case 0x03:
661 return new LDRSBW64_IMM(machInst, rt, rnsp, imm12);
662 case 0x04:
663 return new STRBFP64_IMM(machInst, rt, rnsp, imm12);
664 case 0x05:
665 return new LDRBFP64_IMM(machInst, rt, rnsp, imm12);
666 case 0x06:
667 return new BigFpMemImm("str", machInst, false,
668 rt, rnsp, imm12 << 4);
669 case 0x07:
670 return new BigFpMemImm("ldr", machInst, true,
671 rt, rnsp, imm12 << 4);
672 case 0x08:
673 return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1);
674 case 0x09:
675 return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1);
676 case 0x0a:
677 return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1);
678 case 0x0b:
679 return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1);
680 case 0x0c:
681 return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
682 case 0x0d:
683 return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
684 case 0x10:
685 return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2);
686 case 0x11:
687 return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2);
688 case 0x12:
689 return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2);
690 case 0x14:
691 return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
692 case 0x15:
693 return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
694 case 0x18:
695 return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3);
696 case 0x19:
697 return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3);
698 case 0x1a:
699 return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3);
700 case 0x1c:
701 return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
702 case 0x1d:
703 return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
704 default:
705 return new Unknown64(machInst);
706 }
707 } else if (bits(machInst, 21) == 1) {
708 if (bits(machInst, 11, 10) != 0x2)
709 return new Unknown64(machInst);
710 if (!bits(machInst, 14))
711 return new Unknown64(machInst);
712 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
713 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
714 IntRegIndex rnsp = makeSP(rn);
715 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
716 ArmExtendType type =
717 (ArmExtendType)(uint32_t)bits(machInst, 15, 13);
718 uint8_t s = bits(machInst, 12);
719 switch (switchVal) {
720 case 0x00:
721 return new STRB64_REG(machInst, rt, rnsp, rm, type, 0);
722 case 0x01:
723 return new LDRB64_REG(machInst, rt, rnsp, rm, type, 0);
724 case 0x02:
725 return new LDRSBX64_REG(machInst, rt, rnsp, rm, type, 0);
726 case 0x03:
727 return new LDRSBW64_REG(machInst, rt, rnsp, rm, type, 0);
728 case 0x04:
729 return new STRBFP64_REG(machInst, rt, rnsp, rm, type, 0);
730 case 0x05:
731 return new LDRBFP64_REG(machInst, rt, rnsp, rm, type, 0);
732 case 0x6:
733 return new BigFpMemReg("str", machInst, false,
734 rt, rnsp, rm, type, s * 4);
735 case 0x7:
736 return new BigFpMemReg("ldr", machInst, true,
737 rt, rnsp, rm, type, s * 4);
738 case 0x08:
739 return new STRH64_REG(machInst, rt, rnsp, rm, type, s);
740 case 0x09:
741 return new LDRH64_REG(machInst, rt, rnsp, rm, type, s);
742 case 0x0a:
743 return new LDRSHX64_REG(machInst, rt, rnsp, rm, type, s);
744 case 0x0b:
745 return new LDRSHW64_REG(machInst, rt, rnsp, rm, type, s);
746 case 0x0c:
747 return new STRHFP64_REG(machInst, rt, rnsp, rm, type, s);
748 case 0x0d:
749 return new LDRHFP64_REG(machInst, rt, rnsp, rm, type, s);
750 case 0x10:
751 return new STRW64_REG(machInst, rt, rnsp, rm, type, s * 2);
752 case 0x11:
753 return new LDRW64_REG(machInst, rt, rnsp, rm, type, s * 2);
754 case 0x12:
755 return new LDRSW64_REG(machInst, rt, rnsp, rm, type, s * 2);
756 case 0x14:
757 return new STRSFP64_REG(machInst, rt, rnsp, rm, type, s * 2);
758 case 0x15:
759 return new LDRSFP64_REG(machInst, rt, rnsp, rm, type, s * 2);
760 case 0x18:
761 return new STRX64_REG(machInst, rt, rnsp, rm, type, s * 3);
762 case 0x19:
763 return new LDRX64_REG(machInst, rt, rnsp, rm, type, s * 3);
764 case 0x1a:
765 return new PRFM64_REG(machInst, rt, rnsp, rm, type, s * 3);
766 case 0x1c:
767 return new STRDFP64_REG(machInst, rt, rnsp, rm, type, s * 3);
768 case 0x1d:
769 return new LDRDFP64_REG(machInst, rt, rnsp, rm, type, s * 3);
770 default:
771 return new Unknown64(machInst);
772 }
773 } else {
774 // bit 29:27=111, 25:24=00, 21=0
775 switch (bits(machInst, 11, 10)) {
776 case 0x0:
777 {
778 IntRegIndex rt =
779 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
780 IntRegIndex rn =
781 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
782 IntRegIndex rnsp = makeSP(rn);
783 uint64_t imm = sext<9>(bits(machInst, 20, 12));
784 switch (switchVal) {
785 case 0x00:
786 return new STURB64_IMM(machInst, rt, rnsp, imm);
787 case 0x01:
788 return new LDURB64_IMM(machInst, rt, rnsp, imm);
789 case 0x02:
790 return new LDURSBX64_IMM(machInst, rt, rnsp, imm);
791 case 0x03:
792 return new LDURSBW64_IMM(machInst, rt, rnsp, imm);
793 case 0x04:
794 return new STURBFP64_IMM(machInst, rt, rnsp, imm);
795 case 0x05:
796 return new LDURBFP64_IMM(machInst, rt, rnsp, imm);
797 case 0x06:
798 return new BigFpMemImm("stur", machInst, false,
799 rt, rnsp, imm);
800 case 0x07:
801 return new BigFpMemImm("ldur", machInst, true,
802 rt, rnsp, imm);
803 case 0x08:
804 return new STURH64_IMM(machInst, rt, rnsp, imm);
805 case 0x09:
806 return new LDURH64_IMM(machInst, rt, rnsp, imm);
807 case 0x0a:
808 return new LDURSHX64_IMM(machInst, rt, rnsp, imm);
809 case 0x0b:
810 return new LDURSHW64_IMM(machInst, rt, rnsp, imm);
811 case 0x0c:
812 return new STURHFP64_IMM(machInst, rt, rnsp, imm);
813 case 0x0d:
814 return new LDURHFP64_IMM(machInst, rt, rnsp, imm);
815 case 0x10:
816 return new STURW64_IMM(machInst, rt, rnsp, imm);
817 case 0x11:
818 return new LDURW64_IMM(machInst, rt, rnsp, imm);
819 case 0x12:
820 return new LDURSW64_IMM(machInst, rt, rnsp, imm);
821 case 0x14:
822 return new STURSFP64_IMM(machInst, rt, rnsp, imm);
823 case 0x15:
824 return new LDURSFP64_IMM(machInst, rt, rnsp, imm);
825 case 0x18:
826 return new STURX64_IMM(machInst, rt, rnsp, imm);
827 case 0x19:
828 return new LDURX64_IMM(machInst, rt, rnsp, imm);
829 case 0x1a:
830 return new PRFUM64_IMM(machInst, rt, rnsp, imm);
831 case 0x1c:
832 return new STURDFP64_IMM(machInst, rt, rnsp, imm);
833 case 0x1d:
834 return new LDURDFP64_IMM(machInst, rt, rnsp, imm);
835 default:
836 return new Unknown64(machInst);
837 }
838 }
839 // bit 29:27=111, 25:24=00, 21=0, 11:10=01
840 case 0x1:
841 {
842 IntRegIndex rt =
843 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
844 IntRegIndex rn =
845 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
846 IntRegIndex rnsp = makeSP(rn);
847 uint64_t imm = sext<9>(bits(machInst, 20, 12));
848 switch (switchVal) {
849 case 0x00:
850 return new STRB64_POST(machInst, rt, rnsp, imm);
851 case 0x01:
852 return new LDRB64_POST(machInst, rt, rnsp, imm);
853 case 0x02:
854 return new LDRSBX64_POST(machInst, rt, rnsp, imm);
855 case 0x03:
856 return new LDRSBW64_POST(machInst, rt, rnsp, imm);
857 case 0x04:
858 return new STRBFP64_POST(machInst, rt, rnsp, imm);
859 case 0x05:
860 return new LDRBFP64_POST(machInst, rt, rnsp, imm);
861 case 0x06:
862 return new BigFpMemPost("str", machInst, false,
863 rt, rnsp, imm);
864 case 0x07:
865 return new BigFpMemPost("ldr", machInst, true,
866 rt, rnsp, imm);
867 case 0x08:
868 return new STRH64_POST(machInst, rt, rnsp, imm);
869 case 0x09:
870 return new LDRH64_POST(machInst, rt, rnsp, imm);
871 case 0x0a:
872 return new LDRSHX64_POST(machInst, rt, rnsp, imm);
873 case 0x0b:
874 return new LDRSHW64_POST(machInst, rt, rnsp, imm);
875 case 0x0c:
876 return new STRHFP64_POST(machInst, rt, rnsp, imm);
877 case 0x0d:
878 return new LDRHFP64_POST(machInst, rt, rnsp, imm);
879 case 0x10:
880 return new STRW64_POST(machInst, rt, rnsp, imm);
881 case 0x11:
882 return new LDRW64_POST(machInst, rt, rnsp, imm);
883 case 0x12:
884 return new LDRSW64_POST(machInst, rt, rnsp, imm);
885 case 0x14:
886 return new STRSFP64_POST(machInst, rt, rnsp, imm);
887 case 0x15:
888 return new LDRSFP64_POST(machInst, rt, rnsp, imm);
889 case 0x18:
890 return new STRX64_POST(machInst, rt, rnsp, imm);
891 case 0x19:
892 return new LDRX64_POST(machInst, rt, rnsp, imm);
893 case 0x1c:
894 return new STRDFP64_POST(machInst, rt, rnsp, imm);
895 case 0x1d:
896 return new LDRDFP64_POST(machInst, rt, rnsp, imm);
897 default:
898 return new Unknown64(machInst);
899 }
900 }
901 case 0x2:
902 {
903 IntRegIndex rt =
904 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
905 IntRegIndex rn =
906 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
907 IntRegIndex rnsp = makeSP(rn);
908 uint64_t imm = sext<9>(bits(machInst, 20, 12));
909 switch (switchVal) {
910 case 0x00:
911 return new STTRB64_IMM(machInst, rt, rnsp, imm);
912 case 0x01:
913 return new LDTRB64_IMM(machInst, rt, rnsp, imm);
914 case 0x02:
915 return new LDTRSBX64_IMM(machInst, rt, rnsp, imm);
916 case 0x03:
917 return new LDTRSBW64_IMM(machInst, rt, rnsp, imm);
918 case 0x08:
919 return new STTRH64_IMM(machInst, rt, rnsp, imm);
920 case 0x09:
921 return new LDTRH64_IMM(machInst, rt, rnsp, imm);
922 case 0x0a:
923 return new LDTRSHX64_IMM(machInst, rt, rnsp, imm);
924 case 0x0b:
925 return new LDTRSHW64_IMM(machInst, rt, rnsp, imm);
926 case 0x10:
927 return new STTRW64_IMM(machInst, rt, rnsp, imm);
928 case 0x11:
929 return new LDTRW64_IMM(machInst, rt, rnsp, imm);
930 case 0x12:
931 return new LDTRSW64_IMM(machInst, rt, rnsp, imm);
932 case 0x18:
933 return new STTRX64_IMM(machInst, rt, rnsp, imm);
934 case 0x19:
935 return new LDTRX64_IMM(machInst, rt, rnsp, imm);
936 default:
937 return new Unknown64(machInst);
938 }
939 }
940 case 0x3:
941 {
942 IntRegIndex rt =
943 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
944 IntRegIndex rn =
945 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
946 IntRegIndex rnsp = makeSP(rn);
947 uint64_t imm = sext<9>(bits(machInst, 20, 12));
948 switch (switchVal) {
949 case 0x00:
950 return new STRB64_PRE(machInst, rt, rnsp, imm);
951 case 0x01:
952 return new LDRB64_PRE(machInst, rt, rnsp, imm);
953 case 0x02:
954 return new LDRSBX64_PRE(machInst, rt, rnsp, imm);
955 case 0x03:
956 return new LDRSBW64_PRE(machInst, rt, rnsp, imm);
957 case 0x04:
958 return new STRBFP64_PRE(machInst, rt, rnsp, imm);
959 case 0x05:
960 return new LDRBFP64_PRE(machInst, rt, rnsp, imm);
961 case 0x06:
962 return new BigFpMemPre("str", machInst, false,
963 rt, rnsp, imm);
964 case 0x07:
965 return new BigFpMemPre("ldr", machInst, true,
966 rt, rnsp, imm);
967 case 0x08:
968 return new STRH64_PRE(machInst, rt, rnsp, imm);
969 case 0x09:
970 return new LDRH64_PRE(machInst, rt, rnsp, imm);
971 case 0x0a:
972 return new LDRSHX64_PRE(machInst, rt, rnsp, imm);
973 case 0x0b:
974 return new LDRSHW64_PRE(machInst, rt, rnsp, imm);
975 case 0x0c:
976 return new STRHFP64_PRE(machInst, rt, rnsp, imm);
977 case 0x0d:
978 return new LDRHFP64_PRE(machInst, rt, rnsp, imm);
979 case 0x10:
980 return new STRW64_PRE(machInst, rt, rnsp, imm);
981 case 0x11:
982 return new LDRW64_PRE(machInst, rt, rnsp, imm);
983 case 0x12:
984 return new LDRSW64_PRE(machInst, rt, rnsp, imm);
985 case 0x14:
986 return new STRSFP64_PRE(machInst, rt, rnsp, imm);
987 case 0x15:
988 return new LDRSFP64_PRE(machInst, rt, rnsp, imm);
989 case 0x18:
990 return new STRX64_PRE(machInst, rt, rnsp, imm);
991 case 0x19:
992 return new LDRX64_PRE(machInst, rt, rnsp, imm);
993 case 0x1c:
994 return new STRDFP64_PRE(machInst, rt, rnsp, imm);
995 case 0x1d:
996 return new LDRDFP64_PRE(machInst, rt, rnsp, imm);
997 default:
998 return new Unknown64(machInst);
999 }
1000 }
1001 }
1002 }
1003 }
1004 }
1005 return new FailUnimplemented("Unhandled Case1", machInst);
1006 }
1007}
1008}};
1009
1010output decoder {{
1011namespace Aarch64
1012{
1013 StaticInstPtr
1014 decodeDataProcReg(ExtMachInst machInst)
1015 {
1016 uint8_t switchVal = (bits(machInst, 28) << 1) |
1017 (bits(machInst, 24) << 0);
1018 switch (switchVal) {
1019 case 0x0:
1020 {
1021 uint8_t switchVal = (bits(machInst, 21) << 0) |
1022 (bits(machInst, 30, 29) << 1);
1023 ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1024 uint8_t imm6 = bits(machInst, 15, 10);
1025 bool sf = bits(machInst, 31);
1026 if (!sf && (imm6 & 0x20))
1027 return new Unknown64(machInst);
1028 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1029 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1030 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1031
1032 switch (switchVal) {
1033 case 0x0:
1034 return new AndXSReg(machInst, rd, rn, rm, imm6, type);
1035 case 0x1:
1036 return new BicXSReg(machInst, rd, rn, rm, imm6, type);
1037 case 0x2:
1038 return new OrrXSReg(machInst, rd, rn, rm, imm6, type);
1039 case 0x3:
1040 return new OrnXSReg(machInst, rd, rn, rm, imm6, type);
1041 case 0x4:
1042 return new EorXSReg(machInst, rd, rn, rm, imm6, type);
1043 case 0x5:
1044 return new EonXSReg(machInst, rd, rn, rm, imm6, type);
1045 case 0x6:
1046 return new AndXSRegCc(machInst, rd, rn, rm, imm6, type);
1047 case 0x7:
1048 return new BicXSRegCc(machInst, rd, rn, rm, imm6, type);
1049 }
1050 }
1051 case 0x1:
1052 {
1053 uint8_t switchVal = bits(machInst, 30, 29);
1054 if (bits(machInst, 21) == 0) {
1055 ArmShiftType type =
1056 (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1057 if (type == ROR)
1058 return new Unknown64(machInst);
1059 uint8_t imm6 = bits(machInst, 15, 10);
1060 if (!bits(machInst, 31) && bits(imm6, 5))
1061 return new Unknown64(machInst);
1062 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1063 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1064 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1065 switch (switchVal) {
1066 case 0x0:
1067 return new AddXSReg(machInst, rd, rn, rm, imm6, type);
1068 case 0x1:
1069 return new AddXSRegCc(machInst, rd, rn, rm, imm6, type);
1070 case 0x2:
1071 return new SubXSReg(machInst, rd, rn, rm, imm6, type);
1072 case 0x3:
1073 return new SubXSRegCc(machInst, rd, rn, rm, imm6, type);
1074 }
1075 } else {
1076 if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4)
1077 return new Unknown64(machInst);
1078 ArmExtendType type =
1079 (ArmExtendType)(uint8_t)bits(machInst, 15, 13);
1080 uint8_t imm3 = bits(machInst, 12, 10);
1081 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1082 IntRegIndex rdsp = makeSP(rd);
1083 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1084 IntRegIndex rnsp = makeSP(rn);
1085 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1086
1087 switch (switchVal) {
1088 case 0x0:
1089 return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1090 case 0x1:
1091 return new AddXERegCc(machInst, rd, rnsp, rm, type, imm3);
1092 case 0x2:
1093 return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1094 case 0x3:
1095 return new SubXERegCc(machInst, rd, rnsp, rm, type, imm3);
1096 }
1097 }
1098 }
1099 case 0x2:
1100 {
1101 if (bits(machInst, 21) == 1)
1102 return new Unknown64(machInst);
1103 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1104 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1105 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1106 switch (bits(machInst, 23, 22)) {
1107 case 0x0:
1108 {
1109 if (bits(machInst, 15, 10))
1110 return new Unknown64(machInst);
1111 uint8_t switchVal = bits(machInst, 30, 29);
1112 switch (switchVal) {
1113 case 0x0:
1114 return new AdcXSReg(machInst, rd, rn, rm, 0, LSL);
1115 case 0x1:
1116 return new AdcXSRegCc(machInst, rd, rn, rm, 0, LSL);
1117 case 0x2:
1118 return new SbcXSReg(machInst, rd, rn, rm, 0, LSL);
1119 case 0x3:
1120 return new SbcXSRegCc(machInst, rd, rn, rm, 0, LSL);
1121 }
1122 }
1123 case 0x1:
1124 {
1125 if ((bits(machInst, 4) == 1) ||
1126 (bits(machInst, 10) == 1) ||
1127 (bits(machInst, 29) == 0)) {
1128 return new Unknown64(machInst);
1129 }
1130 ConditionCode cond =
1131 (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1132 uint8_t flags = bits(machInst, 3, 0);
1133 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1134 if (bits(machInst, 11) == 0) {
1135 IntRegIndex rm =
1136 (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1137 if (bits(machInst, 30) == 0) {
1138 return new CcmnReg64(machInst, rn, rm, cond, flags);
1139 } else {
1140 return new CcmpReg64(machInst, rn, rm, cond, flags);
1141 }
1142 } else {
1143 uint8_t imm5 = bits(machInst, 20, 16);
1144 if (bits(machInst, 30) == 0) {
1145 return new CcmnImm64(machInst, rn, imm5, cond, flags);
1146 } else {
1147 return new CcmpImm64(machInst, rn, imm5, cond, flags);
1148 }
1149 }
1150 }
1151 case 0x2:
1152 {
1153 if (bits(machInst, 29) == 1 ||
1154 bits(machInst, 11) == 1) {
1155 return new Unknown64(machInst);
1156 }
1157 uint8_t switchVal = (bits(machInst, 10) << 0) |
1158 (bits(machInst, 30) << 1);
1159 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1160 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1161 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1162 ConditionCode cond =
1163 (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1164 switch (switchVal) {
1165 case 0x0:
1166 return new Csel64(machInst, rd, rn, rm, cond);
1167 case 0x1:
1168 return new Csinc64(machInst, rd, rn, rm, cond);
1169 case 0x2:
1170 return new Csinv64(machInst, rd, rn, rm, cond);
1171 case 0x3:
1172 return new Csneg64(machInst, rd, rn, rm, cond);
1173 }
1174 }
1175 case 0x3:
1176 if (bits(machInst, 30) == 0) {
1177 if (bits(machInst, 29) != 0)
1178 return new Unknown64(machInst);
1179 uint8_t switchVal = bits(machInst, 15, 10);
1180 switch (switchVal) {
1181 case 0x2:
1182 return new Udiv64(machInst, rd, rn, rm);
1183 case 0x3:
1184 return new Sdiv64(machInst, rd, rn, rm);
1185 case 0x8:
1186 return new Lslv64(machInst, rd, rn, rm);
1187 case 0x9:
1188 return new Lsrv64(machInst, rd, rn, rm);
1189 case 0xa:
1190 return new Asrv64(machInst, rd, rn, rm);
1191 case 0xb:
1192 return new Rorv64(machInst, rd, rn, rm);
1193 default:
1194 return new Unknown64(machInst);
1195 }
1196 } else {
1197 if (bits(machInst, 20, 16) != 0 ||
1198 bits(machInst, 29) != 0) {
1199 return new Unknown64(machInst);
1200 }
1201 uint8_t switchVal = bits(machInst, 15, 10);
1202 switch (switchVal) {
1203 case 0x0:
1204 return new Rbit64(machInst, rd, rn);
1205 case 0x1:
1206 return new Rev1664(machInst, rd, rn);
1207 case 0x2:
1208 if (bits(machInst, 31) == 0)
1209 return new Rev64(machInst, rd, rn);
1210 else
1211 return new Rev3264(machInst, rd, rn);
1212 case 0x3:
1213 if (bits(machInst, 31) != 1)
1214 return new Unknown64(machInst);
1215 return new Rev64(machInst, rd, rn);
1216 case 0x4:
1217 return new Clz64(machInst, rd, rn);
1218 case 0x5:
1219 return new Cls64(machInst, rd, rn);
1220 }
1221 }
1222 }
1223 }
1224 case 0x3:
1225 {
1226 if (bits(machInst, 30, 29) != 0x0 ||
1227 (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0))
1228 return new Unknown64(machInst);
1229 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1230 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1231 IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
1232 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1233 switch (bits(machInst, 23, 21)) {
1234 case 0x0:
1235 if (bits(machInst, 15) == 0)
1236 return new Madd64(machInst, rd, ra, rn, rm);
1237 else
1238 return new Msub64(machInst, rd, ra, rn, rm);
1239 case 0x1:
1240 if (bits(machInst, 15) == 0)
1241 return new Smaddl64(machInst, rd, ra, rn, rm);
1242 else
1243 return new Smsubl64(machInst, rd, ra, rn, rm);
1244 case 0x2:
1245 if (bits(machInst, 15) != 0)
1246 return new Unknown64(machInst);
1247 return new Smulh64(machInst, rd, rn, rm);
1248 case 0x5:
1249 if (bits(machInst, 15) == 0)
1250 return new Umaddl64(machInst, rd, ra, rn, rm);
1251 else
1252 return new Umsubl64(machInst, rd, ra, rn, rm);
1253 case 0x6:
1254 if (bits(machInst, 15) != 0)
1255 return new Unknown64(machInst);
1256 return new Umulh64(machInst, rd, rn, rm);
1257 default:
1258 return new Unknown64(machInst);
1259 }
1260 }
1261 }
1262 return new FailUnimplemented("Unhandled Case2", machInst);
1263 }
1264}
1265}};
1266
1267output decoder {{
1268namespace Aarch64
1269{
1270 StaticInstPtr
1271 decodeAdvSIMD(ExtMachInst machInst)
1272 {
1273 if (bits(machInst, 24) == 1) {
1274 if (bits(machInst, 10) == 0) {
1275 return decodeNeonIndexedElem(machInst);
1276 } else if (bits(machInst, 23) == 1) {
1277 return new Unknown64(machInst);
1278 } else {
1279 if (bits(machInst, 22, 19)) {
1280 return decodeNeonShiftByImm(machInst);
1281 } else {
1282 return decodeNeonModImm(machInst);
1283 }
1284 }
1285 } else if (bits(machInst, 21) == 1) {
1286 if (bits(machInst, 10) == 1) {
1287 return decodeNeon3Same(machInst);
1288 } else if (bits(machInst, 11) == 0) {
1289 return decodeNeon3Diff(machInst);
1290 } else if (bits(machInst, 20, 17) == 0x0) {
1291 return decodeNeon2RegMisc(machInst);
1292 } else if (bits(machInst, 20, 17) == 0x8) {
1293 return decodeNeonAcrossLanes(machInst);
1294 } else {
1295 return new Unknown64(machInst);
1296 }
1297 } else if (bits(machInst, 24) ||
1298 bits(machInst, 21) ||
1299 bits(machInst, 15)) {
1300 return new Unknown64(machInst);
1301 } else if (bits(machInst, 10) == 1) {
1302 if (bits(machInst, 23, 22))
1303 return new Unknown64(machInst);
1304 return decodeNeonCopy(machInst);
1305 } else if (bits(machInst, 29) == 1) {
1306 return decodeNeonExt(machInst);
1307 } else if (bits(machInst, 11) == 1) {
1308 return decodeNeonZipUzpTrn(machInst);
1309 } else if (bits(machInst, 23, 22) == 0x0) {
1310 return decodeNeonTblTbx(machInst);
1311 } else {
1312 return new Unknown64(machInst);
1313 }
1314 return new FailUnimplemented("Unhandled Case3", machInst);
1315 }
1316}
1317}};
1318
1319
1320output decoder {{
1321namespace Aarch64
1322{
1323 StaticInstPtr
1324 // bit 30=0, 28:25=1111
1325 decodeFp(ExtMachInst machInst)
1326 {
1327 if (bits(machInst, 24) == 1) {
1328 if (bits(machInst, 31) || bits(machInst, 29))
1329 return new Unknown64(machInst);
1330 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1331 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1332 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
1333 IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 14, 10);
1334 uint8_t switchVal = (bits(machInst, 23, 21) << 1) |
1335 (bits(machInst, 15) << 0);
1336 switch (switchVal) {
1337 case 0x0: // FMADD Sd = Sa + Sn*Sm
1338 return new FMAddS(machInst, rd, rn, rm, ra);
1339 case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm
1340 return new FMSubS(machInst, rd, rn, rm, ra);
1341 case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm
1342 return new FNMAddS(machInst, rd, rn, rm, ra);
1343 case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm
1344 return new FNMSubS(machInst, rd, rn, rm, ra);
1345 case 0x4: // FMADD Dd = Da + Dn*Dm
1346 return new FMAddD(machInst, rd, rn, rm, ra);
1347 case 0x5: // FMSUB Dd = Da + (-Dn)*Dm
1348 return new FMSubD(machInst, rd, rn, rm, ra);
1349 case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm
1350 return new FNMAddD(machInst, rd, rn, rm, ra);
1351 case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm
1352 return new FNMSubD(machInst, rd, rn, rm, ra);
1353 default:
1354 return new Unknown64(machInst);
1355 }
1356 } else if (bits(machInst, 21) == 0) {
1357 bool s = bits(machInst, 29);
1358 if (s)
1359 return new Unknown64(machInst);
1360 uint8_t switchVal = bits(machInst, 20, 16);
1361 uint8_t type = bits(machInst, 23, 22);
1362 uint8_t scale = bits(machInst, 15, 10);
1363 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1364 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1365 if (bits(machInst, 18, 17) == 3 && scale != 0)
1366 return new Unknown64(machInst);
1367 // 30:24=0011110, 21=0
1368 switch (switchVal) {
1369 case 0x00:
1370 return new FailUnimplemented("fcvtns", machInst);
1371 case 0x01:
1372 return new FailUnimplemented("fcvtnu", machInst);
1373 case 0x02:
1374 switch ( (bits(machInst, 31) << 2) | type ) {
1375 case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits))
1376 return new FcvtSFixedFpSW(machInst, rd, rn, scale);
1377 case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits))
1378 return new FcvtSFixedFpDW(machInst, rd, rn, scale);
1379 case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits))
1380 return new FcvtSFixedFpSX(machInst, rd, rn, scale);
1381 case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits))
1382 return new FcvtSFixedFpDX(machInst, rd, rn, scale);
1383 default:
1384 return new Unknown64(machInst);
1385 }
1386 case 0x03:
1387 switch ( (bits(machInst, 31) << 2) | type ) {
1388 case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits))
1389 return new FcvtUFixedFpSW(machInst, rd, rn, scale);
1390 case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits))
1391 return new FcvtUFixedFpDW(machInst, rd, rn, scale);
1392 case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits))
1393 return new FcvtUFixedFpSX(machInst, rd, rn, scale);
1394 case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits))
1395 return new FcvtUFixedFpDX(machInst, rd, rn, scale);
1396 default:
1397 return new Unknown64(machInst);
1398 }
1399 case 0x04:
1400 return new FailUnimplemented("fcvtas", machInst);
1401 case 0x05:
1402 return new FailUnimplemented("fcvtau", machInst);
1403 case 0x08:
1404 return new FailUnimplemented("fcvtps", machInst);
1405 case 0x09:
1406 return new FailUnimplemented("fcvtpu", machInst);
1407 case 0x0e:
1408 return new FailUnimplemented("fmov elem. to 64", machInst);
1409 case 0x0f:
1410 return new FailUnimplemented("fmov 64 bit", machInst);
1411 case 0x10:
1412 return new FailUnimplemented("fcvtms", machInst);
1413 case 0x11:
1414 return new FailUnimplemented("fcvtmu", machInst);
1415 case 0x18:
1416 switch ( (bits(machInst, 31) << 2) | type ) {
1417 case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits))
1418 return new FcvtFpSFixedSW(machInst, rd, rn, scale);
1419 case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits))
1420 return new FcvtFpSFixedDW(machInst, rd, rn, scale);
1421 case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits))
1422 return new FcvtFpSFixedSX(machInst, rd, rn, scale);
1423 case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits))
1424 return new FcvtFpSFixedDX(machInst, rd, rn, scale);
1425 default:
1426 return new Unknown64(machInst);
1427 }
1428 case 0x19:
1429 switch ( (bits(machInst, 31) << 2) | type ) {
1430 case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits))
1431 return new FcvtFpUFixedSW(machInst, rd, rn, scale);
1432 case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits))
1433 return new FcvtFpUFixedDW(machInst, rd, rn, scale);
1434 case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits))
1435 return new FcvtFpUFixedSX(machInst, rd, rn, scale);
1436 case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits))
1437 return new FcvtFpUFixedDX(machInst, rd, rn, scale);
1438 default:
1439 return new Unknown64(machInst);
1440 }
1441 }
1442 } else {
1443 // 30=0, 28:24=11110, 21=1
1444 uint8_t type = bits(machInst, 23, 22);
1445 uint8_t imm8 = bits(machInst, 20, 13);
1446 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1447 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1448 switch (bits(machInst, 11, 10)) {
1449 case 0x0:
1450 if (bits(machInst, 12) == 1) {
1451 if (bits(machInst, 31) ||
1452 bits(machInst, 29) ||
1453 bits(machInst, 9, 5)) {
1454 return new Unknown64(machInst);
1455 }
1456 // 31:29=000, 28:24=11110, 21=1, 12:10=100
1457 if (type == 0) {
1458 // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5)
1459 // :imm8<5:0>:Zeros(19)
1460 uint32_t imm = vfp_modified_imm(imm8, false);
1461 return new FmovImmS(machInst, rd, imm);
1462 } else if (type == 1) {
1463 // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8)
1464 // :imm8<5:0>:Zeros(48)
1465 uint64_t imm = vfp_modified_imm(imm8, true);
1466 return new FmovImmD(machInst, rd, imm);
1467 } else {
1468 return new Unknown64(machInst);
1469 }
1470 } else if (bits(machInst, 13) == 1) {
1471 if (bits(machInst, 31) ||
1472 bits(machInst, 29) ||
1473 bits(machInst, 15, 14) ||
1474 bits(machInst, 23) ||
1475 bits(machInst, 2, 0)) {
1476 return new Unknown64(machInst);
1477 }
1478 uint8_t switchVal = (bits(machInst, 4, 3) << 0) |
1479 (bits(machInst, 22) << 2);
1480 IntRegIndex rm = (IntRegIndex)(uint32_t)
1481 bits(machInst, 20, 16);
1482 // 28:23=000111100, 21=1, 15:10=001000, 2:0=000
1483 switch (switchVal) {
1484 case 0x0:
1485 // FCMP flags = compareQuiet(Sn,Sm)
1486 return new FCmpRegS(machInst, rn, rm);
1487 case 0x1:
1488 // FCMP flags = compareQuiet(Sn,0.0)
1489 return new FCmpImmS(machInst, rn, 0);
1490 case 0x2:
1491 // FCMPE flags = compareSignaling(Sn,Sm)
1492 return new FCmpERegS(machInst, rn, rm);
1493 case 0x3:
1494 // FCMPE flags = compareSignaling(Sn,0.0)
1495 return new FCmpEImmS(machInst, rn, 0);
1496 case 0x4:
1497 // FCMP flags = compareQuiet(Dn,Dm)
1498 return new FCmpRegD(machInst, rn, rm);
1499 case 0x5:
1500 // FCMP flags = compareQuiet(Dn,0.0)
1501 return new FCmpImmD(machInst, rn, 0);
1502 case 0x6:
1503 // FCMPE flags = compareSignaling(Dn,Dm)
1504 return new FCmpERegD(machInst, rn, rm);
1505 case 0x7:
1506 // FCMPE flags = compareSignaling(Dn,0.0)
1507 return new FCmpEImmD(machInst, rn, 0);
1508 default:
1509 return new Unknown64(machInst);
1510 }
1511 } else if (bits(machInst, 14) == 1) {
1512 if (bits(machInst, 31) || bits(machInst, 29))
1513 return new Unknown64(machInst);
1514 uint8_t opcode = bits(machInst, 20, 15);
1515 // Bits 31:24=00011110, 21=1, 14:10=10000
1516 switch (opcode) {
1517 case 0x0:
1518 if (type == 0)
1519 // FMOV Sd = Sn
1520 return new FmovRegS(machInst, rd, rn);
1521 else if (type == 1)
1522 // FMOV Dd = Dn
1523 return new FmovRegD(machInst, rd, rn);
1524 break;
1525 case 0x1:
1526 if (type == 0)
1527 // FABS Sd = abs(Sn)
1528 return new FAbsS(machInst, rd, rn);
1529 else if (type == 1)
1530 // FABS Dd = abs(Dn)
1531 return new FAbsD(machInst, rd, rn);
1532 break;
1533 case 0x2:
1534 if (type == 0)
1535 // FNEG Sd = -Sn
1536 return new FNegS(machInst, rd, rn);
1537 else if (type == 1)
1538 // FNEG Dd = -Dn
1539 return new FNegD(machInst, rd, rn);
1540 break;
1541 case 0x3:
1542 if (type == 0)
1543 // FSQRT Sd = sqrt(Sn)
1544 return new FSqrtS(machInst, rd, rn);
1545 else if (type == 1)
1546 // FSQRT Dd = sqrt(Dn)
1547 return new FSqrtD(machInst, rd, rn);
1548 break;
1549 case 0x4:
1550 if (type == 1)
1551 // FCVT Sd = convertFormat(Dn)
1552 return new FcvtFpDFpS(machInst, rd, rn);
1553 else if (type == 3)
1554 // FCVT Sd = convertFormat(Hn)
1555 return new FcvtFpHFpS(machInst, rd, rn);
1556 break;
1557 case 0x5:
1558 if (type == 0)
1559 // FCVT Dd = convertFormat(Sn)
1560 return new FCvtFpSFpD(machInst, rd, rn);
1561 else if (type == 3)
1562 // FCVT Dd = convertFormat(Hn)
1563 return new FcvtFpHFpD(machInst, rd, rn);
1564 break;
1565 case 0x7:
1566 if (type == 0)
1567 // FCVT Hd = convertFormat(Sn)
1568 return new FcvtFpSFpH(machInst, rd, rn);
1569 else if (type == 1)
1570 // FCVT Hd = convertFormat(Dn)
1571 return new FcvtFpDFpH(machInst, rd, rn);
1572 break;
1573 case 0x8:
1574 if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn)
1575 return new FRIntNS(machInst, rd, rn);
1576 else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn)
1577 return new FRIntND(machInst, rd, rn);
1578 break;
1579 case 0x9:
1580 if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn)
1581 return new FRIntPS(machInst, rd, rn);
1582 else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn)
1583 return new FRIntPD(machInst, rd, rn);
1584 break;
1585 case 0xa:
1586 if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn)
1587 return new FRIntMS(machInst, rd, rn);
1588 else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn)
1589 return new FRIntMD(machInst, rd, rn);
1590 break;
1591 case 0xb:
1592 if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn)
1593 return new FRIntZS(machInst, rd, rn);
1594 else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn)
1595 return new FRIntZD(machInst, rd, rn);
1596 break;
1597 case 0xc:
1598 if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn)
1599 return new FRIntAS(machInst, rd, rn);
1600 else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn)
1601 return new FRIntAD(machInst, rd, rn);
1602 break;
1603 case 0xe:
1604 if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn)
1605 return new FRIntXS(machInst, rd, rn);
1606 else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn)
1607 return new FRIntXD(machInst, rd, rn);
1608 break;
1609 case 0xf:
1610 if (type == 0) // FRINTI Sd = roundToIntegral(Sn)
1611 return new FRIntIS(machInst, rd, rn);
1612 else if (type == 1) // FRINTI Dd = roundToIntegral(Dn)
1613 return new FRIntID(machInst, rd, rn);
1614 break;
1615 default:
1616 return new Unknown64(machInst);
1617 }
1618 return new Unknown64(machInst);
1619 } else if (bits(machInst, 15) == 1) {
1620 return new Unknown64(machInst);
1621 } else {
1622 if (bits(machInst, 29))
1623 return new Unknown64(machInst);
1624 uint8_t rmode = bits(machInst, 20, 19);
1625 uint8_t switchVal1 = bits(machInst, 18, 16);
1626 uint8_t switchVal2 = (type << 1) | bits(machInst, 31);
1627 // 30:24=0011110, 21=1, 15:10=000000
1628 switch (switchVal1) {
1629 case 0x0:
1630 switch ((switchVal2 << 2) | rmode) {
1631 case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn)
1632 return new FcvtFpSIntWSN(machInst, rd, rn);
1633 case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn)
1634 return new FcvtFpSIntWSP(machInst, rd, rn);
1635 case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn)
1636 return new FcvtFpSIntWSM(machInst, rd, rn);
1637 case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn)
1638 return new FcvtFpSIntWSZ(machInst, rd, rn);
1639 case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn)
1640 return new FcvtFpSIntXSN(machInst, rd, rn);
1641 case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn)
1642 return new FcvtFpSIntXSP(machInst, rd, rn);
1643 case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn)
1644 return new FcvtFpSIntXSM(machInst, rd, rn);
1645 case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn)
1646 return new FcvtFpSIntXSZ(machInst, rd, rn);
1647 case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn)
1648 return new FcvtFpSIntWDN(machInst, rd, rn);
1649 case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn)
1650 return new FcvtFpSIntWDP(machInst, rd, rn);
1651 case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn)
1652 return new FcvtFpSIntWDM(machInst, rd, rn);
1653 case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn)
1654 return new FcvtFpSIntWDZ(machInst, rd, rn);
1655 case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn)
1656 return new FcvtFpSIntXDN(machInst, rd, rn);
1657 case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn)
1658 return new FcvtFpSIntXDP(machInst, rd, rn);
1659 case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn)
1660 return new FcvtFpSIntXDM(machInst, rd, rn);
1661 case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn)
1662 return new FcvtFpSIntXDZ(machInst, rd, rn);
1663 default:
1664 return new Unknown64(machInst);
1665 }
1666 case 0x1:
1667 switch ((switchVal2 << 2) | rmode) {
1668 case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn)
1669 return new FcvtFpUIntWSN(machInst, rd, rn);
1670 case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn)
1671 return new FcvtFpUIntWSP(machInst, rd, rn);
1672 case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn)
1673 return new FcvtFpUIntWSM(machInst, rd, rn);
1674 case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn)
1675 return new FcvtFpUIntWSZ(machInst, rd, rn);
1676 case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn)
1677 return new FcvtFpUIntXSN(machInst, rd, rn);
1678 case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn)
1679 return new FcvtFpUIntXSP(machInst, rd, rn);
1680 case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn)
1681 return new FcvtFpUIntXSM(machInst, rd, rn);
1682 case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn)
1683 return new FcvtFpUIntXSZ(machInst, rd, rn);
1684 case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn)
1685 return new FcvtFpUIntWDN(machInst, rd, rn);
1686 case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn)
1687 return new FcvtFpUIntWDP(machInst, rd, rn);
1688 case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn)
1689 return new FcvtFpUIntWDM(machInst, rd, rn);
1690 case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn)
1691 return new FcvtFpUIntWDZ(machInst, rd, rn);
1692 case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn)
1693 return new FcvtFpUIntXDN(machInst, rd, rn);
1694 case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn)
1695 return new FcvtFpUIntXDP(machInst, rd, rn);
1696 case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn)
1697 return new FcvtFpUIntXDM(machInst, rd, rn);
1698 case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn)
1699 return new FcvtFpUIntXDZ(machInst, rd, rn);
1700 default:
1701 return new Unknown64(machInst);
1702 }
1703 case 0x2:
1704 if (rmode != 0)
1705 return new Unknown64(machInst);
1706 switch (switchVal2) {
1707 case 0: // SCVTF Sd = convertFromInt(Wn)
1708 return new FcvtWSIntFpS(machInst, rd, rn);
1709 case 1: // SCVTF Sd = convertFromInt(Xn)
1710 return new FcvtXSIntFpS(machInst, rd, rn);
1711 case 2: // SCVTF Dd = convertFromInt(Wn)
1712 return new FcvtWSIntFpD(machInst, rd, rn);
1713 case 3: // SCVTF Dd = convertFromInt(Xn)
1714 return new FcvtXSIntFpD(machInst, rd, rn);
1715 default:
1716 return new Unknown64(machInst);
1717 }
1718 case 0x3:
1719 switch (switchVal2) {
1720 case 0: // UCVTF Sd = convertFromInt(Wn)
1721 return new FcvtWUIntFpS(machInst, rd, rn);
1722 case 1: // UCVTF Sd = convertFromInt(Xn)
1723 return new FcvtXUIntFpS(machInst, rd, rn);
1724 case 2: // UCVTF Dd = convertFromInt(Wn)
1725 return new FcvtWUIntFpD(machInst, rd, rn);
1726 case 3: // UCVTF Dd = convertFromInt(Xn)
1727 return new FcvtXUIntFpD(machInst, rd, rn);
1728 default:
1729 return new Unknown64(machInst);
1730 }
1731 case 0x4:
1732 if (rmode != 0)
1733 return new Unknown64(machInst);
1734 switch (switchVal2) {
1735 case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn)
1736 return new FcvtFpSIntWSA(machInst, rd, rn);
1737 case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn)
1738 return new FcvtFpSIntXSA(machInst, rd, rn);
1739 case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
1740 return new FcvtFpSIntWDA(machInst, rd, rn);
1741 case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
1742 return new FcvtFpSIntXDA(machInst, rd, rn);
1743 default:
1744 return new Unknown64(machInst);
1745 }
1746 case 0x5:
1747 switch (switchVal2) {
1748 case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn)
1749 return new FcvtFpUIntWSA(machInst, rd, rn);
1750 case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn)
1751 return new FcvtFpUIntXSA(machInst, rd, rn);
1752 case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn)
1753 return new FcvtFpUIntWDA(machInst, rd, rn);
1754 case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn)
1755 return new FcvtFpUIntXDA(machInst, rd, rn);
1756 default:
1757 return new Unknown64(machInst);
1758 }
1759 case 0x06:
1760 switch (switchVal2) {
1761 case 0: // FMOV Wd = Sn
1762 if (rmode != 0)
1763 return new Unknown64(machInst);
1764 return new FmovRegCoreW(machInst, rd, rn);
1765 case 3: // FMOV Xd = Dn
1766 if (rmode != 0)
1767 return new Unknown64(machInst);
1768 return new FmovRegCoreX(machInst, rd, rn);
1769 case 5: // FMOV Xd = Vn<127:64>
1770 if (rmode != 1)
1771 return new Unknown64(machInst);
1772 return new FmovURegCoreX(machInst, rd, rn);
1773 default:
1774 return new Unknown64(machInst);
1775 }
1776 break;
1777 case 0x07:
1778 switch (switchVal2) {
1779 case 0: // FMOV Sd = Wn
1780 if (rmode != 0)
1781 return new Unknown64(machInst);
1782 return new FmovCoreRegW(machInst, rd, rn);
1783 case 3: // FMOV Xd = Dn
1784 if (rmode != 0)
1785 return new Unknown64(machInst);
1786 return new FmovCoreRegX(machInst, rd, rn);
1787 case 5: // FMOV Xd = Vn<127:64>
1788 if (rmode != 1)
1789 return new Unknown64(machInst);
1790 return new FmovUCoreRegX(machInst, rd, rn);
1791 default:
1792 return new Unknown64(machInst);
1793 }
1794 break;
1795 default: // Warning! missing cases in switch statement above, that still need to be added
1796 return new Unknown64(machInst);
1797 }
1798 }
1799 case 0x1:
1800 {
1801 if (bits(machInst, 31) ||
1802 bits(machInst, 29) ||
1803 bits(machInst, 23)) {
1804 return new Unknown64(machInst);
1805 }
1806 IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16);
1807 IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5);
1808 uint8_t imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0);
1809 ConditionCode cond =
1810 (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
1811 uint8_t switchVal = (bits(machInst, 4) << 0) |
1812 (bits(machInst, 22) << 1);
1813 // 31:23=000111100, 21=1, 11:10=01
1814 switch (switchVal) {
1815 case 0x0:
1816 // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv
1817 return new FCCmpRegS(machInst, rn, rm, cond, imm);
1818 case 0x1:
1819 // FCCMP flags = if cond then compareSignaling(Sn,Sm)
1820 // else #nzcv
1821 return new FCCmpERegS(machInst, rn, rm, cond, imm);
1822 case 0x2:
1823 // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv
1824 return new FCCmpRegD(machInst, rn, rm, cond, imm);
1825 case 0x3:
1826 // FCCMP flags = if cond then compareSignaling(Dn,Dm)
1827 // else #nzcv
1828 return new FCCmpERegD(machInst, rn, rm, cond, imm);
1829 default:
1830 return new Unknown64(machInst);
1831 }
1832 }
1833 case 0x2:
1834 {
1835 if (bits(machInst, 31) ||
1836 bits(machInst, 29) ||
1837 bits(machInst, 23)) {
1838 return new Unknown64(machInst);
1839 }
1840 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1841 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1842 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
1843 uint8_t switchVal = (bits(machInst, 15, 12) << 0) |
1844 (bits(machInst, 22) << 4);
1845 switch (switchVal) {
1846 case 0x00: // FMUL Sd = Sn * Sm
1847 return new FMulS(machInst, rd, rn, rm);
1848 case 0x10: // FMUL Dd = Dn * Dm
1849 return new FMulD(machInst, rd, rn, rm);
1850 case 0x01: // FDIV Sd = Sn / Sm
1851 return new FDivS(machInst, rd, rn, rm);
1852 case 0x11: // FDIV Dd = Dn / Dm
1853 return new FDivD(machInst, rd, rn, rm);
1854 case 0x02: // FADD Sd = Sn + Sm
1855 return new FAddS(machInst, rd, rn, rm);
1856 case 0x12: // FADD Dd = Dn + Dm
1857 return new FAddD(machInst, rd, rn, rm);
1858 case 0x03: // FSUB Sd = Sn - Sm
1859 return new FSubS(machInst, rd, rn, rm);
1860 case 0x13: // FSUB Dd = Dn - Dm
1861 return new FSubD(machInst, rd, rn, rm);
1862 case 0x04: // FMAX Sd = max(Sn, Sm)
1863 return new FMaxS(machInst, rd, rn, rm);
1864 case 0x14: // FMAX Dd = max(Dn, Dm)
1865 return new FMaxD(machInst, rd, rn, rm);
1866 case 0x05: // FMIN Sd = min(Sn, Sm)
1867 return new FMinS(machInst, rd, rn, rm);
1868 case 0x15: // FMIN Dd = min(Dn, Dm)
1869 return new FMinD(machInst, rd, rn, rm);
1870 case 0x06: // FMAXNM Sd = maxNum(Sn, Sm)
1871 return new FMaxNMS(machInst, rd, rn, rm);
1872 case 0x16: // FMAXNM Dd = maxNum(Dn, Dm)
1873 return new FMaxNMD(machInst, rd, rn, rm);
1874 case 0x07: // FMINNM Sd = minNum(Sn, Sm)
1875 return new FMinNMS(machInst, rd, rn, rm);
1876 case 0x17: // FMINNM Dd = minNum(Dn, Dm)
1877 return new FMinNMD(machInst, rd, rn, rm);
1878 case 0x08: // FNMUL Sd = -(Sn * Sm)
1879 return new FNMulS(machInst, rd, rn, rm);
1880 case 0x18: // FNMUL Dd = -(Dn * Dm)
1881 return new FNMulD(machInst, rd, rn, rm);
1882 default:
1883 return new Unknown64(machInst);
1884 }
1885 }
1886 case 0x3:
1887 {
1888 if (bits(machInst, 31) || bits(machInst, 29))
1889 return new Unknown64(machInst);
1890 uint8_t type = bits(machInst, 23, 22);
1891 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1892 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1893 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
1894 ConditionCode cond =
1895 (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
1896 if (type == 0) // FCSEL Sd = if cond then Sn else Sm
1897 return new FCSelS(machInst, rd, rn, rm, cond);
1898 else if (type == 1) // FCSEL Dd = if cond then Dn else Dm
1899 return new FCSelD(machInst, rd, rn, rm, cond);
1900 else
1901 return new Unknown64(machInst);
1902 }
1903 }
1904 }
1905 return new FailUnimplemented("Unhandled Case4", machInst);
1906 }
1907}
1908}};
1909
1910output decoder {{
1911namespace Aarch64
1912{
1913 StaticInstPtr
1914 decodeAdvSIMDScalar(ExtMachInst machInst)
1915 {
1916 if (bits(machInst, 24) == 1) {
1917 if (bits(machInst, 10) == 0) {
1918 return decodeNeonScIndexedElem(machInst);
1919 } else if (bits(machInst, 23) == 0) {
1920 return decodeNeonScShiftByImm(machInst);
1921 }
1922 } else if (bits(machInst, 21) == 1) {
1923 if (bits(machInst, 10) == 1) {
1924 return decodeNeonSc3Same(machInst);
1925 } else if (bits(machInst, 11) == 0) {
1926 return decodeNeonSc3Diff(machInst);
1927 } else if (bits(machInst, 20, 17) == 0x0) {
1928 return decodeNeonSc2RegMisc(machInst);
1929 } else if (bits(machInst, 20, 17) == 0x8) {
1930 return decodeNeonScPwise(machInst);
1931 } else {
1932 return new Unknown64(machInst);
1933 }
1934 } else if (bits(machInst, 23, 22) == 0 &&
1935 bits(machInst, 15) == 0 &&
1936 bits(machInst, 10) == 1) {
1937 return decodeNeonScCopy(machInst);
1938 } else {
1939 return new Unknown64(machInst);
1940 }
1941 return new FailUnimplemented("Unhandled Case6", machInst);
1942 }
1943}
1944}};
1945
1946output decoder {{
1947namespace Aarch64
1948{
1949 StaticInstPtr
1950 decodeFpAdvSIMD(ExtMachInst machInst)
1951 {
1952
1953 if (bits(machInst, 28) == 0) {
1954 if (bits(machInst, 31) == 0) {
1955 return decodeAdvSIMD(machInst);
1956 } else {
1957 return new Unknown64(machInst);
1958 }
1959 } else if (bits(machInst, 30) == 0) {
1960 return decodeFp(machInst);
1961 } else if (bits(machInst, 31) == 0) {
1962 return decodeAdvSIMDScalar(machInst);
1963 } else {
1964 return new Unknown64(machInst);
1965 }
1966 }
1967}
1968}};
1969
1970output decoder {{
1971namespace Aarch64
1972{
1973 StaticInstPtr
1974 decodeGem5Ops(ExtMachInst machInst)
1975 {
1976 const uint32_t m5func = bits(machInst, 23, 16);
1977 switch (m5func) {
1978 case 0x00: return new Arm(machInst);
1979 case 0x01: return new Quiesce(machInst);
1980 case 0x02: return new QuiesceNs64(machInst);
1981 case 0x03: return new QuiesceCycles64(machInst);
1982 case 0x04: return new QuiesceTime64(machInst);
1983 case 0x07: return new Rpns64(machInst);
1984 case 0x09: return new WakeCPU64(machInst);
1985 case 0x10: return new Deprecated_ivlb(machInst);
1986 case 0x11: return new Deprecated_ivle(machInst);
1987 case 0x20: return new Deprecated_exit (machInst);
1988 case 0x21: return new M5exit64(machInst);
1989 case 0x31: return new Loadsymbol(machInst);
1990 case 0x30: return new Initparam64(machInst);
1991 case 0x40: return new Resetstats64(machInst);
1992 case 0x41: return new Dumpstats64(machInst);
1993 case 0x42: return new Dumpresetstats64(machInst);
1994 case 0x43: return new M5checkpoint64(machInst);
1995 case 0x4F: return new M5writefile64(machInst);
1996 case 0x50: return new M5readfile64(machInst);
1997 case 0x51: return new M5break(machInst);
1998 case 0x52: return new M5switchcpu(machInst);
1999 case 0x53: return new M5addsymbol64(machInst);
2000 case 0x54: return new M5panic(machInst);
2001 case 0x5a: return new M5workbegin64(machInst);
2002 case 0x5b: return new M5workend64(machInst);
2003 default: return new Unknown64(machInst);
2004 }
2005 }
2006}
2007}};
2008
2009def format Aarch64() {{
2010 decode_block = '''
2011 {
2012 using namespace Aarch64;
2013 if (bits(machInst, 27) == 0x0) {
2014 if (bits(machInst, 28) == 0x0)
2015 return new Unknown64(machInst);
2016 else if (bits(machInst, 26) == 0)
2017 // bit 28:26=100
2018 return decodeDataProcImm(machInst);
2019 else
2020 // bit 28:26=101
2021 return decodeBranchExcSys(machInst);
2022 } else if (bits(machInst, 25) == 0) {
2023 // bit 27=1, 25=0
2024 return decodeLoadsStores(machInst);
2025 } else if (bits(machInst, 26) == 0) {
2026 // bit 27:25=101
2027 return decodeDataProcReg(machInst);
2028 } else if (bits(machInst, 24) == 1 &&
2029 bits(machInst, 31, 28) == 0xF) {
2030 return decodeGem5Ops(machInst);
2031 } else {
2032 // bit 27:25=111
2033 return decodeFpAdvSIMD(machInst);
2034 }
2035 }
2036 '''
2037}};