1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
|
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "decode.h"
#include "pcode.h"
int BitCount(uint32_t x)
{
int result = 0;
while (x)
{
if (x & 1)
result += 1;
x >>= 1;
}
return result;
}
bool BFXPreferred(uint32_t sf, uint32_t uns, uint32_t imms, uint32_t immr)
{
// must not match UBFIZ/SBFIX alias
if (imms < immr)
return false;
// must not match LSR/ASR/LSL alias (imms == 31 or 63)
if (imms == ((sf << 5) | 0x1F))
return false;
// must not match UXTx/SXTx alias
if (immr == 0)
{
// must not match 32-bit UXT[BH] or SXT[BH]
if (sf == 0 && (imms == 7 || imms == 15))
return false;
// must not match 64-bit SXT[BHW]
if ((sf == 1 && uns == 0) && (imms == 7 || imms == 15 || imms == 31))
return false;
}
// must be UBFX/SBFX alias
return true;
}
uint64_t rotate_right(uint64_t x, unsigned width, unsigned amount)
{
amount = amount % width;
x = (x >> amount) | (x << (width - amount));
x = (width < 64) ? x & (((uint64_t)1 << width) - 1) : x;
return x;
}
DecodeBitMasks_ReturnType DecodeBitMasks(
uint8_t /*bit*/ immN, uint8_t /*bit(6)*/ imms, uint8_t /*bit(6)*/ immr)
{
int ones_nbits = 0;
if (immN == 1)
ones_nbits = 6;
else if ((imms & 0x3E) == 0x3C)
ones_nbits = 1;
else if ((imms & 0x3C) == 0x38)
ones_nbits = 2;
else if ((imms & 0x38) == 0x30)
ones_nbits = 3;
else if ((imms & 0x30) == 0x20)
ones_nbits = 4;
else if ((imms & 0x20) == 0)
ones_nbits = 5;
// TODO else: return undefined
/* set 1's in element */
int ones_n = (imms & ((1 << ones_nbits) - 1)) + 1;
uint64_t result = ((uint64_t)1 << ones_n) - 1;
/* rotate element */
int elem_width = 1 << ones_nbits;
result = rotate_right(result, elem_width, immr);
/* replicate element */
while (elem_width < 64)
{
result = (result << elem_width) | result;
elem_width *= 2;
}
DecodeBitMasks_ReturnType dbmrt;
// TODO: do this right
dbmrt.wmask = result;
dbmrt.tmask = result;
return dbmrt;
}
/* idea to abandon pseudocode and compute+compare actual bitmask
is from NetBSD sys/arch/aarch64/aarch64/disasm.c */
bool MoveWidePreferred(uint32_t sf, uint32_t immN, uint32_t immS, uint32_t immR)
{
uint32_t splat = (immN << 6) | immS;
if (sf == 1 && !((splat & 0x40) == 0x40))
return false;
if (sf == 0 && !((splat & 0x60) == 0x00))
return false;
DecodeBitMasks_ReturnType dbmrt = DecodeBitMasks(sf, immS, immR);
uint64_t imm = dbmrt.wmask;
/* MOVZ check, at most 16 zeroes not across halfword (16-bit) boundary */
if (sf == 0)
imm &= 0xffffffff;
if (((imm & 0xffffffffffff0000) == 0) || ((imm & 0xffffffff0000ffff) == 0) ||
((imm & 0xffff0000ffffffff) == 0) || ((imm & 0x0000ffffffffffff) == 0))
return true;
/* MOVN check, at most 16 ones not across halfword (16-bit) boundary */
imm = ~imm;
if (sf == 0)
imm &= 0xffffffff;
if (((imm & 0xffffffffffff0000) == 0) || ((imm & 0xffffffff0000ffff) == 0) ||
((imm & 0xffff0000ffffffff) == 0) || ((imm & 0x0000ffffffffffff) == 0))
return true;
return false;
}
int HighestSetBit(uint64_t x)
{
for (int i = 63; i >= 0 && x; --i)
{
if (x & 0x8000000000000000)
return i;
x <<= 1;
}
return -1;
}
int LowestSetBit(uint64_t x)
{
for (int i = 0; i < 64; ++i)
{
if (x & 1)
return i;
x >>= 1;
}
return -1;
}
bool SVEMoveMaskPreferred(uint32_t imm13)
{
// TODO: populate this
return true;
}
enum ShiftType DecodeRegExtend(uint8_t op)
{
switch (op & 7)
{
case 0b000:
return ShiftType_UXTB;
case 0b001:
return ShiftType_UXTH;
case 0b010:
return ShiftType_UXTW;
case 0b011:
return ShiftType_UXTX;
case 0b100:
return ShiftType_SXTB;
case 0b101:
return ShiftType_SXTH;
case 0b110:
return ShiftType_SXTW;
case 0b111:
return ShiftType_SXTX;
default:
return ShiftType_NONE;
}
}
enum ShiftType DecodeShift(uint8_t op)
{
switch (op & 3)
{
case 0b00:
return ShiftType_LSL;
case 0b01:
return ShiftType_LSR;
case 0b10:
return ShiftType_ASR;
case 0b11:
return ShiftType_ROR;
default:
return ShiftType_NONE;
}
}
enum SystemOp SysOp(uint32_t op1, uint32_t CRn, uint32_t CRm, uint32_t op2)
{
uint32_t tmp = (op1 << 11) | (CRn << 7) | (CRm << 3) | op2;
switch (tmp)
{
case 0b00001111000000:
return Sys_AT; // S1E1R
case 0b10001111000000:
return Sys_AT; // S1E2R
case 0b11001111000000:
return Sys_AT; // S1E3R
case 0b00001111000001:
return Sys_AT; // S1E1W
case 0b00001111001001:
return Sys_AT; // S1E1WP
case 0b10001111000001:
return Sys_AT; // S1E2W
case 0b11001111000001:
return Sys_AT; // S1E3W
case 0b00001111000010:
return Sys_AT; // S1E0R
case 0b00001111000011:
return Sys_AT; // S1E0W
case 0b10001111000100:
return Sys_AT; // S12E1R
case 0b10001111000101:
return Sys_AT; // S12E1W
case 0b10001111000110:
return Sys_AT; // S12E0R
case 0b10001111000111:
return Sys_AT; // S12E0W
case 0b01101110100001:
return Sys_DC; // ZVA
case 0b00001110110001:
return Sys_DC; // IVAC
case 0b00001110110010:
return Sys_DC; // ISW
case 0b01101111010001:
return Sys_DC; // CVAC
case 0b00001111010010:
return Sys_DC; // CSW
case 0b01101111011001:
return Sys_DC; // CVAU
case 0b01101111110001:
return Sys_DC; // CIVAC
case 0b00001111110010:
return Sys_DC; // CISW
case 0b01101111101001:
return Sys_DC; // CVADP
case 0b00001110001000:
return Sys_IC; // IALLUIS
case 0b00001110101000:
return Sys_IC; // IALLU
case 0b01101110101001:
return Sys_IC; // IVAU
case 0b10010000000001:
return Sys_TLBI; // IPAS2E1IS
case 0b10010000000101:
return Sys_TLBI; // IPAS2LE1IS
case 0b00010000011000:
return Sys_TLBI; // VMALLE1IS
case 0b10010000011000:
return Sys_TLBI; // ALLE2IS
case 0b11010000011000:
return Sys_TLBI; // ALLE3IS
case 0b00010000011001:
return Sys_TLBI; // VAE1IS
case 0b10010000011001:
return Sys_TLBI; // VAE2IS
case 0b11010000011001:
return Sys_TLBI; // VAE3IS
case 0b00010000011010:
return Sys_TLBI; // ASIDE1IS
case 0b00010000011011:
return Sys_TLBI; // VAAE1IS
case 0b10010000011100:
return Sys_TLBI; // ALLE1IS
case 0b00010000011101:
return Sys_TLBI; // VALE1IS
case 0b10010000011101:
return Sys_TLBI; // VALE2IS
case 0b11010000011101:
return Sys_TLBI; // VALE3IS
case 0b10010000011110:
return Sys_TLBI; // VMALLS12E1IS
case 0b00010000011111:
return Sys_TLBI; // VAALE1IS
case 0b10010000100001:
return Sys_TLBI; // IPAS2E1
case 0b10010000100101:
return Sys_TLBI; // IPAS2LE1
case 0b00010000111000:
return Sys_TLBI; // VMALLE1
case 0b10010000111000:
return Sys_TLBI; // ALLE2
case 0b11010000111000:
return Sys_TLBI; // ALLE3
case 0b00010000111001:
return Sys_TLBI; // VAE1
case 0b10010000111001:
return Sys_TLBI; // VAE2
case 0b11010000111001:
return Sys_TLBI; // VAE3
case 0b00010000111010:
return Sys_TLBI; // ASIDE1
case 0b00010000111011:
return Sys_TLBI; // VAAE1
case 0b10010000111100:
return Sys_TLBI; // ALLE1
case 0b00010000111101:
return Sys_TLBI; // VALE1
case 0b10010000111101:
return Sys_TLBI; // VALE2
case 0b11010000111101:
return Sys_TLBI; // VALE3
case 0b10010000111110:
return Sys_TLBI; // VMALLS12E1
case 0b00010000111111:
return Sys_TLBI; // VAALE1
default:
return Sys_ERROR;
}
}
uint32_t UInt(uint32_t foo)
{
return foo;
}
uint32_t BitSlice(uint64_t foo, int hi, int lo) // including the endpoints
{
int width = hi - lo + 1;
uint64_t mask = (1 << width) - 1;
return (foo >> lo) & mask;
}
bool IsZero(uint64_t foo)
{
return foo == 0;
}
bool IsOnes(uint64_t foo, int width)
{
return foo == (1 << width) - 1;
}
/* Mozilla MPL
TODO: evaluate license, possibly rewrite
https://github.com/Siguza/iometa/blob/master/src/a64.c */
uint64_t Replicate(uint64_t val, uint8_t times, uint64_t width)
{
// Fast path
switch (times)
{
case 64:
val |= val << width;
width <<= 1;
case 32:
val |= val << width;
width <<= 1;
case 16:
val |= val << width;
width <<= 1;
case 8:
val |= val << width;
width <<= 1;
case 4:
val |= val << width;
width <<= 1;
case 2:
val |= val << width;
case 1:
return val;
case 0:
return 0;
default:
break;
}
// Slow path
uint64_t orig = val;
for (size_t i = 0; i < times; ++i)
{
val <<= width;
val |= orig;
}
return val;
}
/* Mozilla MPL
TODO: evaluate license, possibly rewrite
https://github.com/Siguza/iometa/blob/master/src/a64.c */
uint64_t AdvSIMDExpandImm(uint8_t op, uint8_t cmode, uint64_t imm8)
{
uint64_t imm64;
switch ((cmode >> 1) & 0b111)
{
case 0b000:
imm64 = Replicate(imm8, 2, 32);
break;
case 0b001:
imm64 = Replicate(imm8 << 8, 2, 32);
break;
case 0b010:
imm64 = Replicate(imm8 << 16, 2, 32);
break;
case 0b011:
imm64 = Replicate(imm8 << 24, 2, 32);
break;
case 0b100:
imm64 = Replicate(imm8, 4, 16);
break;
case 0b101:
imm64 = Replicate(imm8 << 8, 4, 16);
break;
case 0b110:
imm64 = Replicate(imm8 << (8 << (cmode & 0b1)), 2, 32);
break;
case 0b111:
switch (((cmode & 0b1) << 1) | op)
{
case 0b00:
imm64 = Replicate(imm8, 8, 8);
break;
case 0b01:
#if 0
imm8a = Replicate((imm8 >> 7) & 0b1, 8, 1);
imm8b = Replicate((imm8 >> 6) & 0b1, 8, 1);
imm8c = Replicate((imm8 >> 5) & 0b1, 8, 1);
imm8d = Replicate((imm8 >> 4) & 0b1, 8, 1);
imm8e = Replicate((imm8 >> 3) & 0b1, 8, 1);
imm8f = Replicate((imm8 >> 2) & 0b1, 8, 1);
imm8g = Replicate((imm8 >> 1) & 0b1, 8, 1);
imm8h = Replicate((imm8 ) & 0b1, 8, 1);
imm64 = (imm8a << 0x38) | (imm8b << 0x30) | (imm8c << 0x28) | (imm8d << 0x20) | (imm8e << 0x18) | (imm8f << 0x10) | (imm8g << 0x08) | imm8h;
#else
imm64 = imm8 | (imm8 << (0x08 - 1)) | (imm8 << (0x10 - 2)) | (imm8 << (0x18 - 3)) |
(imm8 << (0x20 - 4)) | (imm8 << (0x28 - 5)) | (imm8 << (0x30 - 6)) |
(imm8 << (0x38 - 7));
imm64 &= 0x0101010101010101;
imm64 = Replicate(imm64, 8, 1);
#endif
break;
case 0b10:
imm64 = Replicate((((imm8 & 0xc0) ^ 0x80) << 24) |
(Replicate((imm8 >> 6) & 0b1, 5, 1) << 25) | ((imm8 & 0x3f) << 19),
2, 32);
break;
case 0b11:
imm64 = (((imm8 & 0xc0) ^ 0x80) << 56) | (Replicate((imm8 >> 6) & 0b1, 8, 1) << 54) |
((imm8 & 0x3f) << 48);
break;
}
break;
}
return imm64;
}
bool BTypeCompatible_BTI(uint8_t hintcode, uint8_t pstate_btype)
{
switch (hintcode & 3)
{
case 0b00:
return false;
case 0b01:
return pstate_btype != 0b11;
case 0b10:
return pstate_btype != 0b10;
case 0b11:
return true;
}
return false; /* impossible, but appease compiler */
}
bool BTypeCompatible_PACIXSP()
{
// TODO: determine if filling this in is necessary
return true;
}
enum FPRounding FPDecodeRounding(uint8_t RMode)
{
switch (RMode & 3)
{
case 0b00:
return FPRounding_TIEEVEN; // N
case 0b01:
return FPRounding_POSINF; // P
case 0b10:
return FPRounding_NEGINF; // M
case 0b11:
return FPRounding_ZERO; // Z
}
return FPRounding_ERROR;
}
enum FPRounding FPRoundingMode(uint64_t fpcr)
{
return FPDecodeRounding(FPCR_GET_RMode(fpcr));
}
bool HaltingAllowed(void)
{
// TODO: determine if filling this in is necessary
return true;
}
// AArch64.SystemAccessTrap
void SystemAccessTrap(uint32_t a, uint32_t b)
{
// TODO: determine if filling this in is necessary
while (0)
;
}
void CheckSystemAccess(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g)
{
// TODO: determine if filling this in is necessary
while (0)
;
}
// from LLVM
// TODO: check license, determine if rewrite needed
uint64_t VFPExpandImm(unsigned char byte, unsigned N)
{
// assert(N == 32 || N == 64);
uint64_t Result;
unsigned bit6 = SLICE(byte, 6, 6);
if (N == 32)
{
Result = SLICE(byte, 7, 7) << 31 | SLICE(byte, 5, 0) << 19;
if (bit6)
Result |= 0x1f << 25;
else
Result |= 0x1 << 30;
}
else
{
Result = (uint64_t)SLICE(byte, 7, 7) << 63 | (uint64_t)SLICE(byte, 5, 0) << 48;
if (bit6)
Result |= 0xffULL << 54;
else
Result |= 0x1ULL << 62;
}
// return APInt(N, Result);
return Result;
}
bool EL2Enabled(void)
{
// TODO: determine if filling this in is necessary
return true;
}
bool ELUsingAArch32(uint8_t x)
{
// TODO: determine if filling this in is necessary
return true;
}
uint64_t FPOne(bool sign, int N)
{
// width should be 16, 32, 64
int E, F, exp;
switch (N)
{
case 16:
E = 5;
case 32:
E = 8;
default:
E = 11;
}
F = N - (E + 1);
exp = BITMASK(E - 1) << 1;
return (sign << (E - 1 + F)) | (exp << F);
}
uint64_t FPTwo(bool sign, int N)
{
// width should be 16, 32, 64
//int F;
int E, exp;
switch (N)
{
case 16:
E = 5;
case 32:
E = 8;
default:
E = 11;
}
//F = N - (E + 1);
exp = 1 << (E - 1);
return (sign << E) | exp;
}
uint64_t FPPointFive(bool sign, int N)
{
// width should be 16, 32, 64
int E, F, exp;
switch (N)
{
case 16:
E = 5;
case 32:
E = 8;
default:
E = 11;
}
F = N - (E + 1);
exp = BITMASK(E - 2) << 1;
return (sign << (E - 2 + F)) | (exp << F);
}
uint64_t SignExtend(uint64_t x, int width)
{
uint64_t result = -1;
if (x & ((uint64_t)1 << (width - 1)))
{
result ^= (((uint64_t)1 << width) - 1);
result |= x;
}
else
{
result = x;
}
return result;
}
enum Constraint ConstrainUnpredictable(enum Unpredictable u)
{
switch (u)
{
case Unpredictable_VMSR:
return Constraint_UNDEF;
case Unpredictable_WBOVERLAPLD:
return Constraint_WBSUPPRESS; // return loaded value
case Unpredictable_WBOVERLAPST:
return Constraint_NONE; // store pre-writeback value
case Unpredictable_LDPOVERLAP:
return Constraint_UNDEF; // instruction is UNDEFINED
case Unpredictable_BASEOVERLAP:
return Constraint_NONE; // use original address
case Unpredictable_DATAOVERLAP:
return Constraint_NONE; // store original value
case Unpredictable_DEVPAGE2:
return Constraint_FAULT; // take an alignment fault
case Unpredictable_DEVICETAGSTORE:
return Constraint_NONE; // Do not take a fault
case Unpredictable_INSTRDEVICE:
return Constraint_NONE; // Do not take a fault
case Unpredictable_RESCPACR:
return Constraint_TRUE; // Map to UNKNOWN value
case Unpredictable_RESMAIR:
return Constraint_UNKNOWN; // Map to UNKNOWN value
case Unpredictable_RESTEXCB:
return Constraint_UNKNOWN; // Map to UNKNOWN value
case Unpredictable_RESDACR:
return Constraint_UNKNOWN; // Map to UNKNOWN value
case Unpredictable_RESPRRR:
return Constraint_UNKNOWN; // Map to UNKNOWN value
case Unpredictable_RESVTCRS:
return Constraint_UNKNOWN; // Map to UNKNOWN value
case Unpredictable_RESTnSZ:
return Constraint_FORCE; // Map to the limit value
case Unpredictable_OORTnSZ:
return Constraint_FORCE; // Map to the limit value
case Unpredictable_LARGEIPA:
return Constraint_FORCE; // Restrict the inputsize to the PAMax value
case Unpredictable_ESRCONDPASS:
return Constraint_FALSE; // Report as "AL"
case Unpredictable_ILZEROIT:
return Constraint_FALSE; // Do not zero PSTATE.IT
case Unpredictable_ILZEROT:
return Constraint_FALSE; // Do not zero PSTATE.T
case Unpredictable_BPVECTORCATCHPRI:
return Constraint_TRUE; // Debug Vector Catch: match on 2nd halfword
case Unpredictable_VCMATCHHALF:
return Constraint_FALSE; // No match
case Unpredictable_VCMATCHDAPA:
return Constraint_FALSE; // No match on Data Abort or Prefetch abort
case Unpredictable_WPMASKANDBAS:
return Constraint_FALSE; // Watchpoint disabled
case Unpredictable_WPBASCONTIGUOUS:
return Constraint_FALSE; // Watchpoint disabled
case Unpredictable_RESWPMASK:
return Constraint_DISABLED; // Watchpoint disabled
case Unpredictable_WPMASKEDBITS:
return Constraint_FALSE; // Watchpoint disabled
case Unpredictable_RESBPWPCTRL:
return Constraint_DISABLED; // Breakpoint/watchpoint disabled
case Unpredictable_BPNOTIMPL:
return Constraint_DISABLED; // Breakpoint disabled
case Unpredictable_RESBPTYPE:
return Constraint_DISABLED; // Breakpoint disabled
case Unpredictable_BPNOTCTXCMP:
return Constraint_DISABLED; // Breakpoint disabled
case Unpredictable_BPMATCHHALF:
return Constraint_FALSE; // No match
case Unpredictable_BPMISMATCHHALF:
return Constraint_FALSE; // No match
case Unpredictable_RESTARTALIGNPC:
return Constraint_FALSE; // Do not force alignment
case Unpredictable_RESTARTZEROUPPERPC:
return Constraint_TRUE; // Force zero extension
case Unpredictable_ZEROUPPER:
return Constraint_TRUE; // zero top halves of X registers
case Unpredictable_ERETZEROUPPERPC:
return Constraint_TRUE; // zero top half of PC
case Unpredictable_A32FORCEALIGNPC:
return Constraint_FALSE; // Do not force alignment
case Unpredictable_SMD:
return Constraint_UNDEF; // disabled SMC is Unallocated
case Unpredictable_NONFAULT:
return Constraint_FALSE; // Speculation enabled
case Unpredictable_SVEZEROUPPER:
return Constraint_TRUE; // zero top bits of Z registers
case Unpredictable_SVELDNFDATA:
return Constraint_TRUE; // Load mem data in NF loads
case Unpredictable_SVELDNFZERO:
return Constraint_TRUE; // Write zeros in NF loads
case Unpredictable_CHECKSPNONEACTIVE:
return Constraint_TRUE; // Check SP alignment
case Unpredictable_AFUPDATE:
return Constraint_TRUE;
case Unpredictable_IESBinDebug:
return Constraint_TRUE;
case Unpredictable_BADPMSFCR:
return Constraint_TRUE;
case Unpredictable_ZEROBTYPE:
return Constraint_TRUE; // Save BTYPE in SPSR_ELx/DPSR_EL0 as '00'
case Unpredictable_CLEARERRITEZERO:
return Constraint_FALSE;
case Unpredictable_ALUEXCEPTIONRETURN:
return Constraint_UNDEF;
case Unpredictable_DBGxVR_RESS:
return Constraint_FALSE;
case Unpredictable_WFxTDEBUG:
return Constraint_FALSE; // WFxT in Debug state does not execute as a NOP
case Unpredictable_LS64UNSUPPORTED:
return Constraint_LIMITED_ATOMICITY; //
default:
return Constraint_ERROR;
}
}
|