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