1use alloc::boxed::Box;
7#[allow(unused_imports)]
8use alloc::format;
9use alloc::string::String;
10use alloc::vec::Vec;
11use core::fmt;
12
13use crate::error::Span;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub enum Arch {
19 X86,
21 X86_64,
23 Arm,
25 Thumb,
27 Aarch64,
29 Rv32,
31 Rv64,
33}
34
35impl fmt::Display for Arch {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 match self {
38 Arch::X86 => write!(f, "x86"),
39 Arch::X86_64 => write!(f, "x86_64"),
40 Arch::Arm => write!(f, "ARM"),
41 Arch::Thumb => write!(f, "Thumb"),
42 Arch::Aarch64 => write!(f, "AArch64"),
43 Arch::Rv32 => write!(f, "RV32"),
44 Arch::Rv64 => write!(f, "RV64"),
45 }
46 }
47}
48
49impl Arch {
50 #[must_use]
52 pub fn to_arch_name(self) -> crate::error::ArchName {
53 match self {
54 Arch::X86 => crate::error::ArchName::X86,
55 Arch::X86_64 => crate::error::ArchName::X86_64,
56 Arch::Arm => crate::error::ArchName::Arm,
57 Arch::Thumb => crate::error::ArchName::Thumb,
58 Arch::Aarch64 => crate::error::ArchName::Aarch64,
59 Arch::Rv32 => crate::error::ArchName::Rv32,
60 Arch::Rv64 => crate::error::ArchName::Rv64,
61 }
62 }
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
67#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
68pub enum Syntax {
69 Intel,
71 Att,
73 Ual,
75 RiscV,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
81#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
82pub enum OptLevel {
83 None,
85 #[default]
87 Size,
88}
89
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
97#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
98pub enum Register {
99 Rax,
102 Rcx,
104 Rdx,
106 Rbx,
108 Rsp,
110 Rbp,
112 Rsi,
114 Rdi,
116 R8,
118 R9,
120 R10,
122 R11,
124 R12,
126 R13,
128 R14,
130 R15,
132 Eax,
135 Ecx,
137 Edx,
139 Ebx,
141 Esp,
143 Ebp,
145 Esi,
147 Edi,
149 R8d,
151 R9d,
153 R10d,
155 R11d,
157 R12d,
159 R13d,
161 R14d,
163 R15d,
165 Ax,
168 Cx,
170 Dx,
172 Bx,
174 Sp,
176 Bp,
178 Si,
180 Di,
182 R8w,
184 R9w,
186 R10w,
188 R11w,
190 R12w,
192 R13w,
194 R14w,
196 R15w,
198 Al,
201 Cl,
203 Dl,
205 Bl,
207 Spl,
209 Bpl,
211 Sil,
213 Dil,
215 Ah,
217 Ch,
219 Dh,
221 Bh,
223 R8b,
225 R9b,
227 R10b,
229 R11b,
231 R12b,
233 R13b,
235 R14b,
237 R15b,
239 Rip,
242 Eip,
244 Cs,
247 Ds,
249 Es,
251 Fs,
253 Gs,
255 Ss,
257 Xmm0,
260 Xmm1,
262 Xmm2,
264 Xmm3,
266 Xmm4,
268 Xmm5,
270 Xmm6,
272 Xmm7,
274 Xmm8,
276 Xmm9,
278 Xmm10,
280 Xmm11,
282 Xmm12,
284 Xmm13,
286 Xmm14,
288 Xmm15,
290 Ymm0,
293 Ymm1,
295 Ymm2,
297 Ymm3,
299 Ymm4,
301 Ymm5,
303 Ymm6,
305 Ymm7,
307 Ymm8,
309 Ymm9,
311 Ymm10,
313 Ymm11,
315 Ymm12,
317 Ymm13,
319 Ymm14,
321 Ymm15,
323 Zmm0,
326 Zmm1,
328 Zmm2,
330 Zmm3,
332 Zmm4,
334 Zmm5,
336 Zmm6,
338 Zmm7,
340 Zmm8,
342 Zmm9,
344 Zmm10,
346 Zmm11,
348 Zmm12,
350 Zmm13,
352 Zmm14,
354 Zmm15,
356 Zmm16,
358 Zmm17,
360 Zmm18,
362 Zmm19,
364 Zmm20,
366 Zmm21,
368 Zmm22,
370 Zmm23,
372 Zmm24,
374 Zmm25,
376 Zmm26,
378 Zmm27,
380 Zmm28,
382 Zmm29,
384 Zmm30,
386 Zmm31,
388 K0,
391 K1,
393 K2,
395 K3,
397 K4,
399 K5,
401 K6,
403 K7,
405
406 ArmR0,
409 ArmR1,
411 ArmR2,
413 ArmR3,
415 ArmR4,
417 ArmR5,
419 ArmR6,
421 ArmR7,
423 ArmR8,
425 ArmR9,
427 ArmR10,
429 ArmR11,
431 ArmR12,
433 ArmSp,
435 ArmLr,
437 ArmPc,
439 ArmCpsr,
441
442 A64X0,
445 A64X1,
447 A64X2,
449 A64X3,
451 A64X4,
453 A64X5,
455 A64X6,
457 A64X7,
459 A64X8,
461 A64X9,
463 A64X10,
465 A64X11,
467 A64X12,
469 A64X13,
471 A64X14,
473 A64X15,
475 A64X16,
477 A64X17,
479 A64X18,
481 A64X19,
483 A64X20,
485 A64X21,
487 A64X22,
489 A64X23,
491 A64X24,
493 A64X25,
495 A64X26,
497 A64X27,
499 A64X28,
501 A64X29,
503 A64X30,
505 A64Sp,
507 A64Xzr,
509
510 A64W0,
513 A64W1,
515 A64W2,
517 A64W3,
519 A64W4,
521 A64W5,
523 A64W6,
525 A64W7,
527 A64W8,
529 A64W9,
531 A64W10,
533 A64W11,
535 A64W12,
537 A64W13,
539 A64W14,
541 A64W15,
543 A64W16,
545 A64W17,
547 A64W18,
549 A64W19,
551 A64W20,
553 A64W21,
555 A64W22,
557 A64W23,
559 A64W24,
561 A64W25,
563 A64W26,
565 A64W27,
567 A64W28,
569 A64W29,
571 A64W30,
573 A64Wzr,
575
576 A64V0,
579 A64V1,
581 A64V2,
583 A64V3,
585 A64V4,
587 A64V5,
589 A64V6,
591 A64V7,
593 A64V8,
595 A64V9,
597 A64V10,
599 A64V11,
601 A64V12,
603 A64V13,
605 A64V14,
607 A64V15,
609 A64V16,
611 A64V17,
613 A64V18,
615 A64V19,
617 A64V20,
619 A64V21,
621 A64V22,
623 A64V23,
625 A64V24,
627 A64V25,
629 A64V26,
631 A64V27,
633 A64V28,
635 A64V29,
637 A64V30,
639 A64V31,
641
642 A64Q0,
645 A64Q1,
647 A64Q2,
649 A64Q3,
651 A64Q4,
653 A64Q5,
655 A64Q6,
657 A64Q7,
659 A64Q8,
661 A64Q9,
663 A64Q10,
665 A64Q11,
667 A64Q12,
669 A64Q13,
671 A64Q14,
673 A64Q15,
675 A64Q16,
677 A64Q17,
679 A64Q18,
681 A64Q19,
683 A64Q20,
685 A64Q21,
687 A64Q22,
689 A64Q23,
691 A64Q24,
693 A64Q25,
695 A64Q26,
697 A64Q27,
699 A64Q28,
701 A64Q29,
703 A64Q30,
705 A64Q31,
707 A64D0,
709 A64D1,
711 A64D2,
713 A64D3,
715 A64D4,
717 A64D5,
719 A64D6,
721 A64D7,
723 A64D8,
725 A64D9,
727 A64D10,
729 A64D11,
731 A64D12,
733 A64D13,
735 A64D14,
737 A64D15,
739 A64D16,
741 A64D17,
743 A64D18,
745 A64D19,
747 A64D20,
749 A64D21,
751 A64D22,
753 A64D23,
755 A64D24,
757 A64D25,
759 A64D26,
761 A64D27,
763 A64D28,
765 A64D29,
767 A64D30,
769 A64D31,
771 A64S0,
773 A64S1,
775 A64S2,
777 A64S3,
779 A64S4,
781 A64S5,
783 A64S6,
785 A64S7,
787 A64S8,
789 A64S9,
791 A64S10,
793 A64S11,
795 A64S12,
797 A64S13,
799 A64S14,
801 A64S15,
803 A64S16,
805 A64S17,
807 A64S18,
809 A64S19,
811 A64S20,
813 A64S21,
815 A64S22,
817 A64S23,
819 A64S24,
821 A64S25,
823 A64S26,
825 A64S27,
827 A64S28,
829 A64S29,
831 A64S30,
833 A64S31,
835 A64H0,
837 A64H1,
839 A64H2,
841 A64H3,
843 A64H4,
845 A64H5,
847 A64H6,
849 A64H7,
851 A64H8,
853 A64H9,
855 A64H10,
857 A64H11,
859 A64H12,
861 A64H13,
863 A64H14,
865 A64H15,
867 A64H16,
869 A64H17,
871 A64H18,
873 A64H19,
875 A64H20,
877 A64H21,
879 A64H22,
881 A64H23,
883 A64H24,
885 A64H25,
887 A64H26,
889 A64H27,
891 A64H28,
893 A64H29,
895 A64H30,
897 A64H31,
899 A64B0,
901 A64B1,
903 A64B2,
905 A64B3,
907 A64B4,
909 A64B5,
911 A64B6,
913 A64B7,
915 A64B8,
917 A64B9,
919 A64B10,
921 A64B11,
923 A64B12,
925 A64B13,
927 A64B14,
929 A64B15,
931 A64B16,
933 A64B17,
935 A64B18,
937 A64B19,
939 A64B20,
941 A64B21,
943 A64B22,
945 A64B23,
947 A64B24,
949 A64B25,
951 A64B26,
953 A64B27,
955 A64B28,
957 A64B29,
959 A64B30,
961 A64B31,
963
964 A64Z0,
967 A64Z1,
969 A64Z2,
971 A64Z3,
973 A64Z4,
975 A64Z5,
977 A64Z6,
979 A64Z7,
981 A64Z8,
983 A64Z9,
985 A64Z10,
987 A64Z11,
989 A64Z12,
991 A64Z13,
993 A64Z14,
995 A64Z15,
997 A64Z16,
999 A64Z17,
1001 A64Z18,
1003 A64Z19,
1005 A64Z20,
1007 A64Z21,
1009 A64Z22,
1011 A64Z23,
1013 A64Z24,
1015 A64Z25,
1017 A64Z26,
1019 A64Z27,
1021 A64Z28,
1023 A64Z29,
1025 A64Z30,
1027 A64Z31,
1029
1030 A64P0,
1033 A64P1,
1035 A64P2,
1037 A64P3,
1039 A64P4,
1041 A64P5,
1043 A64P6,
1045 A64P7,
1047 A64P8,
1049 A64P9,
1051 A64P10,
1053 A64P11,
1055 A64P12,
1057 A64P13,
1059 A64P14,
1061 A64P15,
1063
1064 RvX0,
1067 RvX1,
1069 RvX2,
1071 RvX3,
1073 RvX4,
1075 RvX5,
1077 RvX6,
1079 RvX7,
1081 RvX8,
1083 RvX9,
1085 RvX10,
1087 RvX11,
1089 RvX12,
1091 RvX13,
1093 RvX14,
1095 RvX15,
1097 RvX16,
1099 RvX17,
1101 RvX18,
1103 RvX19,
1105 RvX20,
1107 RvX21,
1109 RvX22,
1111 RvX23,
1113 RvX24,
1115 RvX25,
1117 RvX26,
1119 RvX27,
1121 RvX28,
1123 RvX29,
1125 RvX30,
1127 RvX31,
1129
1130 RvF0,
1133 RvF1,
1135 RvF2,
1137 RvF3,
1139 RvF4,
1141 RvF5,
1143 RvF6,
1145 RvF7,
1147 RvF8,
1149 RvF9,
1151 RvF10,
1153 RvF11,
1155 RvF12,
1157 RvF13,
1159 RvF14,
1161 RvF15,
1163 RvF16,
1165 RvF17,
1167 RvF18,
1169 RvF19,
1171 RvF20,
1173 RvF21,
1175 RvF22,
1177 RvF23,
1179 RvF24,
1181 RvF25,
1183 RvF26,
1185 RvF27,
1187 RvF28,
1189 RvF29,
1191 RvF30,
1193 RvF31,
1195
1196 RvV0,
1199 RvV1,
1201 RvV2,
1203 RvV3,
1205 RvV4,
1207 RvV5,
1209 RvV6,
1211 RvV7,
1213 RvV8,
1215 RvV9,
1217 RvV10,
1219 RvV11,
1221 RvV12,
1223 RvV13,
1225 RvV14,
1227 RvV15,
1229 RvV16,
1231 RvV17,
1233 RvV18,
1235 RvV19,
1237 RvV20,
1239 RvV21,
1241 RvV22,
1243 RvV23,
1245 RvV24,
1247 RvV25,
1249 RvV26,
1251 RvV27,
1253 RvV28,
1255 RvV29,
1257 RvV30,
1259 RvV31,
1261}
1262
1263impl Register {
1264 pub fn base_code(self) -> u8 {
1266 use Register::*;
1267 match self {
1268 Rax | Eax | Ax | Al | R8 | R8d | R8w | R8b | Xmm0 | Xmm8 | Ymm0 | Ymm8 | Zmm0
1269 | Zmm8 | Zmm16 | Zmm24 | K0 => 0,
1270 Rcx | Ecx | Cx | Cl | R9 | R9d | R9w | R9b | Xmm1 | Xmm9 | Ymm1 | Ymm9 | Zmm1
1271 | Zmm9 | Zmm17 | Zmm25 | K1 => 1,
1272 Rdx | Edx | Dx | Dl | R10 | R10d | R10w | R10b | Xmm2 | Xmm10 | Ymm2 | Ymm10 | Zmm2
1273 | Zmm10 | Zmm18 | Zmm26 | K2 => 2,
1274 Rbx | Ebx | Bx | Bl | R11 | R11d | R11w | R11b | Xmm3 | Xmm11 | Ymm3 | Ymm11 | Zmm3
1275 | Zmm11 | Zmm19 | Zmm27 | K3 => 3,
1276 Rsp | Esp | Sp | Spl | Ah | R12 | R12d | R12w | R12b | Xmm4 | Xmm12 | Ymm4 | Ymm12
1277 | Zmm4 | Zmm12 | Zmm20 | Zmm28 | K4 => 4,
1278 Rbp | Ebp | Bp | Bpl | Ch | R13 | R13d | R13w | R13b | Xmm5 | Xmm13 | Ymm5 | Ymm13
1279 | Zmm5 | Zmm13 | Zmm21 | Zmm29 | K5 => 5,
1280 Rsi | Esi | Si | Sil | Dh | R14 | R14d | R14w | R14b | Xmm6 | Xmm14 | Ymm6 | Ymm14
1281 | Zmm6 | Zmm14 | Zmm22 | Zmm30 | K6 => 6,
1282 Rdi | Edi | Di | Dil | Bh | R15 | R15d | R15w | R15b | Xmm7 | Xmm15 | Ymm7 | Ymm15
1283 | Zmm7 | Zmm15 | Zmm23 | Zmm31 | K7 => 7,
1284 Rip | Eip => 5, Cs => 1,
1286 Ds => 3,
1287 Es => 0,
1288 Fs => 4,
1289 Gs => 5,
1290 Ss => 2,
1291 _ => 0,
1293 }
1294 }
1295
1296 pub fn is_extended(self) -> bool {
1299 use Register::*;
1300 matches!(
1301 self,
1302 R8 | R9
1303 | R10
1304 | R11
1305 | R12
1306 | R13
1307 | R14
1308 | R15
1309 | R8d
1310 | R9d
1311 | R10d
1312 | R11d
1313 | R12d
1314 | R13d
1315 | R14d
1316 | R15d
1317 | R8w
1318 | R9w
1319 | R10w
1320 | R11w
1321 | R12w
1322 | R13w
1323 | R14w
1324 | R15w
1325 | R8b
1326 | R9b
1327 | R10b
1328 | R11b
1329 | R12b
1330 | R13b
1331 | R14b
1332 | R15b
1333 | Xmm8
1334 | Xmm9
1335 | Xmm10
1336 | Xmm11
1337 | Xmm12
1338 | Xmm13
1339 | Xmm14
1340 | Xmm15
1341 | Ymm8
1342 | Ymm9
1343 | Ymm10
1344 | Ymm11
1345 | Ymm12
1346 | Ymm13
1347 | Ymm14
1348 | Ymm15
1349 | Zmm8
1350 | Zmm9
1351 | Zmm10
1352 | Zmm11
1353 | Zmm12
1354 | Zmm13
1355 | Zmm14
1356 | Zmm15
1357 | Zmm24
1358 | Zmm25
1359 | Zmm26
1360 | Zmm27
1361 | Zmm28
1362 | Zmm29
1363 | Zmm30
1364 | Zmm31
1365 )
1366 }
1367
1368 pub fn is_evex_extended(self) -> bool {
1371 use Register::*;
1372 matches!(
1373 self,
1374 Zmm16
1375 | Zmm17
1376 | Zmm18
1377 | Zmm19
1378 | Zmm20
1379 | Zmm21
1380 | Zmm22
1381 | Zmm23
1382 | Zmm24
1383 | Zmm25
1384 | Zmm26
1385 | Zmm27
1386 | Zmm28
1387 | Zmm29
1388 | Zmm30
1389 | Zmm31
1390 )
1391 }
1392
1393 pub fn size_bits(self) -> u16 {
1395 use Register::*;
1396 match self {
1397 Rax | Rcx | Rdx | Rbx | Rsp | Rbp | Rsi | Rdi | R8 | R9 | R10 | R11 | R12 | R13
1398 | R14 | R15 | Rip => 64,
1399 Eax | Ecx | Edx | Ebx | Esp | Ebp | Esi | Edi | R8d | R9d | R10d | R11d | R12d
1400 | R13d | R14d | R15d | Eip => 32,
1401 Ax | Cx | Dx | Bx | Sp | Bp | Si | Di | R8w | R9w | R10w | R11w | R12w | R13w
1402 | R14w | R15w => 16,
1403 Al | Cl | Dl | Bl | Spl | Bpl | Sil | Dil | Ah | Ch | Dh | Bh | R8b | R9b | R10b
1404 | R11b | R12b | R13b | R14b | R15b => 8,
1405 Cs | Ds | Es | Fs | Gs | Ss => 16,
1406 Xmm0 | Xmm1 | Xmm2 | Xmm3 | Xmm4 | Xmm5 | Xmm6 | Xmm7 | Xmm8 | Xmm9 | Xmm10 | Xmm11
1407 | Xmm12 | Xmm13 | Xmm14 | Xmm15 => 128,
1408 Ymm0 | Ymm1 | Ymm2 | Ymm3 | Ymm4 | Ymm5 | Ymm6 | Ymm7 | Ymm8 | Ymm9 | Ymm10 | Ymm11
1409 | Ymm12 | Ymm13 | Ymm14 | Ymm15 => 256,
1410 Zmm0 | Zmm1 | Zmm2 | Zmm3 | Zmm4 | Zmm5 | Zmm6 | Zmm7 | Zmm8 | Zmm9 | Zmm10 | Zmm11
1411 | Zmm12 | Zmm13 | Zmm14 | Zmm15 | Zmm16 | Zmm17 | Zmm18 | Zmm19 | Zmm20 | Zmm21
1412 | Zmm22 | Zmm23 | Zmm24 | Zmm25 | Zmm26 | Zmm27 | Zmm28 | Zmm29 | Zmm30 | Zmm31 => 512,
1413 K0 | K1 | K2 | K3 | K4 | K5 | K6 | K7 => 64,
1414 ArmR0 | ArmR1 | ArmR2 | ArmR3 | ArmR4 | ArmR5 | ArmR6 | ArmR7 | ArmR8 | ArmR9
1416 | ArmR10 | ArmR11 | ArmR12 | ArmSp | ArmLr | ArmPc | ArmCpsr => 32,
1417 A64X0 | A64X1 | A64X2 | A64X3 | A64X4 | A64X5 | A64X6 | A64X7 | A64X8 | A64X9
1419 | A64X10 | A64X11 | A64X12 | A64X13 | A64X14 | A64X15 | A64X16 | A64X17 | A64X18
1420 | A64X19 | A64X20 | A64X21 | A64X22 | A64X23 | A64X24 | A64X25 | A64X26 | A64X27
1421 | A64X28 | A64X29 | A64X30 | A64Sp | A64Xzr => 64,
1422 A64W0 | A64W1 | A64W2 | A64W3 | A64W4 | A64W5 | A64W6 | A64W7 | A64W8 | A64W9
1424 | A64W10 | A64W11 | A64W12 | A64W13 | A64W14 | A64W15 | A64W16 | A64W17 | A64W18
1425 | A64W19 | A64W20 | A64W21 | A64W22 | A64W23 | A64W24 | A64W25 | A64W26 | A64W27
1426 | A64W28 | A64W29 | A64W30 | A64Wzr => 32,
1427 A64V0 | A64V1 | A64V2 | A64V3 | A64V4 | A64V5 | A64V6 | A64V7 | A64V8 | A64V9
1429 | A64V10 | A64V11 | A64V12 | A64V13 | A64V14 | A64V15 | A64V16 | A64V17 | A64V18
1430 | A64V19 | A64V20 | A64V21 | A64V22 | A64V23 | A64V24 | A64V25 | A64V26 | A64V27
1431 | A64V28 | A64V29 | A64V30 | A64V31 | A64Q0 | A64Q1 | A64Q2 | A64Q3 | A64Q4 | A64Q5
1432 | A64Q6 | A64Q7 | A64Q8 | A64Q9 | A64Q10 | A64Q11 | A64Q12 | A64Q13 | A64Q14
1433 | A64Q15 | A64Q16 | A64Q17 | A64Q18 | A64Q19 | A64Q20 | A64Q21 | A64Q22 | A64Q23
1434 | A64Q24 | A64Q25 | A64Q26 | A64Q27 | A64Q28 | A64Q29 | A64Q30 | A64Q31 => 128,
1435 A64D0 | A64D1 | A64D2 | A64D3 | A64D4 | A64D5 | A64D6 | A64D7 | A64D8 | A64D9
1437 | A64D10 | A64D11 | A64D12 | A64D13 | A64D14 | A64D15 | A64D16 | A64D17 | A64D18
1438 | A64D19 | A64D20 | A64D21 | A64D22 | A64D23 | A64D24 | A64D25 | A64D26 | A64D27
1439 | A64D28 | A64D29 | A64D30 | A64D31 => 64,
1440 A64S0 | A64S1 | A64S2 | A64S3 | A64S4 | A64S5 | A64S6 | A64S7 | A64S8 | A64S9
1442 | A64S10 | A64S11 | A64S12 | A64S13 | A64S14 | A64S15 | A64S16 | A64S17 | A64S18
1443 | A64S19 | A64S20 | A64S21 | A64S22 | A64S23 | A64S24 | A64S25 | A64S26 | A64S27
1444 | A64S28 | A64S29 | A64S30 | A64S31 => 32,
1445 A64H0 | A64H1 | A64H2 | A64H3 | A64H4 | A64H5 | A64H6 | A64H7 | A64H8 | A64H9
1447 | A64H10 | A64H11 | A64H12 | A64H13 | A64H14 | A64H15 | A64H16 | A64H17 | A64H18
1448 | A64H19 | A64H20 | A64H21 | A64H22 | A64H23 | A64H24 | A64H25 | A64H26 | A64H27
1449 | A64H28 | A64H29 | A64H30 | A64H31 => 16,
1450 A64B0 | A64B1 | A64B2 | A64B3 | A64B4 | A64B5 | A64B6 | A64B7 | A64B8 | A64B9
1452 | A64B10 | A64B11 | A64B12 | A64B13 | A64B14 | A64B15 | A64B16 | A64B17 | A64B18
1453 | A64B19 | A64B20 | A64B21 | A64B22 | A64B23 | A64B24 | A64B25 | A64B26 | A64B27
1454 | A64B28 | A64B29 | A64B30 | A64B31 => 8,
1455 A64Z0 | A64Z1 | A64Z2 | A64Z3 | A64Z4 | A64Z5 | A64Z6 | A64Z7 | A64Z8 | A64Z9
1457 | A64Z10 | A64Z11 | A64Z12 | A64Z13 | A64Z14 | A64Z15 | A64Z16 | A64Z17 | A64Z18
1458 | A64Z19 | A64Z20 | A64Z21 | A64Z22 | A64Z23 | A64Z24 | A64Z25 | A64Z26 | A64Z27
1459 | A64Z28 | A64Z29 | A64Z30 | A64Z31 => 0,
1460 A64P0 | A64P1 | A64P2 | A64P3 | A64P4 | A64P5 | A64P6 | A64P7 | A64P8 | A64P9
1462 | A64P10 | A64P11 | A64P12 | A64P13 | A64P14 | A64P15 => 0,
1463 RvX0 | RvX1 | RvX2 | RvX3 | RvX4 | RvX5 | RvX6 | RvX7 | RvX8 | RvX9 | RvX10 | RvX11
1466 | RvX12 | RvX13 | RvX14 | RvX15 | RvX16 | RvX17 | RvX18 | RvX19 | RvX20 | RvX21
1467 | RvX22 | RvX23 | RvX24 | RvX25 | RvX26 | RvX27 | RvX28 | RvX29 | RvX30 | RvX31 => 0,
1468 RvF0 | RvF1 | RvF2 | RvF3 | RvF4 | RvF5 | RvF6 | RvF7 | RvF8 | RvF9 | RvF10 | RvF11
1471 | RvF12 | RvF13 | RvF14 | RvF15 | RvF16 | RvF17 | RvF18 | RvF19 | RvF20 | RvF21
1472 | RvF22 | RvF23 | RvF24 | RvF25 | RvF26 | RvF27 | RvF28 | RvF29 | RvF30 | RvF31 => 0,
1473 RvV0 | RvV1 | RvV2 | RvV3 | RvV4 | RvV5 | RvV6 | RvV7 | RvV8 | RvV9 | RvV10 | RvV11
1475 | RvV12 | RvV13 | RvV14 | RvV15 | RvV16 | RvV17 | RvV18 | RvV19 | RvV20 | RvV21
1476 | RvV22 | RvV23 | RvV24 | RvV25 | RvV26 | RvV27 | RvV28 | RvV29 | RvV30 | RvV31 => 0,
1477 }
1478 }
1479
1480 pub fn requires_rex_for_byte(self) -> bool {
1483 use Register::*;
1484 matches!(self, Spl | Bpl | Sil | Dil)
1485 }
1486
1487 pub fn is_high_byte(self) -> bool {
1490 use Register::*;
1491 matches!(self, Ah | Ch | Dh | Bh)
1492 }
1493
1494 #[must_use]
1496 pub fn is_xmm(self) -> bool {
1497 use Register::*;
1498 matches!(
1499 self,
1500 Xmm0 | Xmm1
1501 | Xmm2
1502 | Xmm3
1503 | Xmm4
1504 | Xmm5
1505 | Xmm6
1506 | Xmm7
1507 | Xmm8
1508 | Xmm9
1509 | Xmm10
1510 | Xmm11
1511 | Xmm12
1512 | Xmm13
1513 | Xmm14
1514 | Xmm15
1515 )
1516 }
1517
1518 #[must_use]
1520 pub fn is_ymm(self) -> bool {
1521 use Register::*;
1522 matches!(
1523 self,
1524 Ymm0 | Ymm1
1525 | Ymm2
1526 | Ymm3
1527 | Ymm4
1528 | Ymm5
1529 | Ymm6
1530 | Ymm7
1531 | Ymm8
1532 | Ymm9
1533 | Ymm10
1534 | Ymm11
1535 | Ymm12
1536 | Ymm13
1537 | Ymm14
1538 | Ymm15
1539 )
1540 }
1541
1542 #[must_use]
1544 pub fn is_zmm(self) -> bool {
1545 use Register::*;
1546 matches!(
1547 self,
1548 Zmm0 | Zmm1
1549 | Zmm2
1550 | Zmm3
1551 | Zmm4
1552 | Zmm5
1553 | Zmm6
1554 | Zmm7
1555 | Zmm8
1556 | Zmm9
1557 | Zmm10
1558 | Zmm11
1559 | Zmm12
1560 | Zmm13
1561 | Zmm14
1562 | Zmm15
1563 | Zmm16
1564 | Zmm17
1565 | Zmm18
1566 | Zmm19
1567 | Zmm20
1568 | Zmm21
1569 | Zmm22
1570 | Zmm23
1571 | Zmm24
1572 | Zmm25
1573 | Zmm26
1574 | Zmm27
1575 | Zmm28
1576 | Zmm29
1577 | Zmm30
1578 | Zmm31
1579 )
1580 }
1581
1582 #[must_use]
1584 pub fn is_opmask(self) -> bool {
1585 use Register::*;
1586 matches!(self, K0 | K1 | K2 | K3 | K4 | K5 | K6 | K7)
1587 }
1588
1589 #[must_use]
1591 pub fn is_vector(self) -> bool {
1592 self.is_xmm() || self.is_ymm() || self.is_zmm()
1593 }
1594
1595 #[must_use]
1601 pub fn to_32bit(self) -> Option<Register> {
1602 use Register::*;
1603 match self {
1604 Rax | Eax => Some(Eax),
1605 Rcx | Ecx => Some(Ecx),
1606 Rdx | Edx => Some(Edx),
1607 Rbx | Ebx => Some(Ebx),
1608 Rsp | Esp => Some(Esp),
1609 Rbp | Ebp => Some(Ebp),
1610 Rsi | Esi => Some(Esi),
1611 Rdi | Edi => Some(Edi),
1612 R8 | R8d => Some(R8d),
1613 R9 | R9d => Some(R9d),
1614 R10 | R10d => Some(R10d),
1615 R11 | R11d => Some(R11d),
1616 R12 | R12d => Some(R12d),
1617 R13 | R13d => Some(R13d),
1618 R14 | R14d => Some(R14d),
1619 R15 | R15d => Some(R15d),
1620 _ => None,
1621 }
1622 }
1623
1624 #[must_use]
1626 pub fn is_arm(self) -> bool {
1627 use Register::*;
1628 matches!(
1629 self,
1630 ArmR0
1631 | ArmR1
1632 | ArmR2
1633 | ArmR3
1634 | ArmR4
1635 | ArmR5
1636 | ArmR6
1637 | ArmR7
1638 | ArmR8
1639 | ArmR9
1640 | ArmR10
1641 | ArmR11
1642 | ArmR12
1643 | ArmSp
1644 | ArmLr
1645 | ArmPc
1646 | ArmCpsr
1647 )
1648 }
1649
1650 #[must_use]
1652 pub fn arm_reg_num(self) -> u8 {
1653 use Register::*;
1654 match self {
1655 ArmR0 => 0,
1656 ArmR1 => 1,
1657 ArmR2 => 2,
1658 ArmR3 => 3,
1659 ArmR4 => 4,
1660 ArmR5 => 5,
1661 ArmR6 => 6,
1662 ArmR7 => 7,
1663 ArmR8 => 8,
1664 ArmR9 => 9,
1665 ArmR10 => 10,
1666 ArmR11 => 11,
1667 ArmR12 => 12,
1668 ArmSp => 13,
1669 ArmLr => 14,
1670 ArmPc => 15,
1671 _ => 0,
1672 }
1673 }
1674
1675 #[must_use]
1677 pub fn is_aarch64(self) -> bool {
1678 use Register::*;
1679 matches!(
1680 self,
1681 A64X0
1682 | A64X1
1683 | A64X2
1684 | A64X3
1685 | A64X4
1686 | A64X5
1687 | A64X6
1688 | A64X7
1689 | A64X8
1690 | A64X9
1691 | A64X10
1692 | A64X11
1693 | A64X12
1694 | A64X13
1695 | A64X14
1696 | A64X15
1697 | A64X16
1698 | A64X17
1699 | A64X18
1700 | A64X19
1701 | A64X20
1702 | A64X21
1703 | A64X22
1704 | A64X23
1705 | A64X24
1706 | A64X25
1707 | A64X26
1708 | A64X27
1709 | A64X28
1710 | A64X29
1711 | A64X30
1712 | A64Sp
1713 | A64Xzr
1714 | A64W0
1715 | A64W1
1716 | A64W2
1717 | A64W3
1718 | A64W4
1719 | A64W5
1720 | A64W6
1721 | A64W7
1722 | A64W8
1723 | A64W9
1724 | A64W10
1725 | A64W11
1726 | A64W12
1727 | A64W13
1728 | A64W14
1729 | A64W15
1730 | A64W16
1731 | A64W17
1732 | A64W18
1733 | A64W19
1734 | A64W20
1735 | A64W21
1736 | A64W22
1737 | A64W23
1738 | A64W24
1739 | A64W25
1740 | A64W26
1741 | A64W27
1742 | A64W28
1743 | A64W29
1744 | A64W30
1745 | A64Wzr
1746 | A64V0
1747 | A64V1
1748 | A64V2
1749 | A64V3
1750 | A64V4
1751 | A64V5
1752 | A64V6
1753 | A64V7
1754 | A64V8
1755 | A64V9
1756 | A64V10
1757 | A64V11
1758 | A64V12
1759 | A64V13
1760 | A64V14
1761 | A64V15
1762 | A64V16
1763 | A64V17
1764 | A64V18
1765 | A64V19
1766 | A64V20
1767 | A64V21
1768 | A64V22
1769 | A64V23
1770 | A64V24
1771 | A64V25
1772 | A64V26
1773 | A64V27
1774 | A64V28
1775 | A64V29
1776 | A64V30
1777 | A64V31
1778 | A64Q0
1779 | A64Q1
1780 | A64Q2
1781 | A64Q3
1782 | A64Q4
1783 | A64Q5
1784 | A64Q6
1785 | A64Q7
1786 | A64Q8
1787 | A64Q9
1788 | A64Q10
1789 | A64Q11
1790 | A64Q12
1791 | A64Q13
1792 | A64Q14
1793 | A64Q15
1794 | A64Q16
1795 | A64Q17
1796 | A64Q18
1797 | A64Q19
1798 | A64Q20
1799 | A64Q21
1800 | A64Q22
1801 | A64Q23
1802 | A64Q24
1803 | A64Q25
1804 | A64Q26
1805 | A64Q27
1806 | A64Q28
1807 | A64Q29
1808 | A64Q30
1809 | A64Q31
1810 | A64D0
1811 | A64D1
1812 | A64D2
1813 | A64D3
1814 | A64D4
1815 | A64D5
1816 | A64D6
1817 | A64D7
1818 | A64D8
1819 | A64D9
1820 | A64D10
1821 | A64D11
1822 | A64D12
1823 | A64D13
1824 | A64D14
1825 | A64D15
1826 | A64D16
1827 | A64D17
1828 | A64D18
1829 | A64D19
1830 | A64D20
1831 | A64D21
1832 | A64D22
1833 | A64D23
1834 | A64D24
1835 | A64D25
1836 | A64D26
1837 | A64D27
1838 | A64D28
1839 | A64D29
1840 | A64D30
1841 | A64D31
1842 | A64S0
1843 | A64S1
1844 | A64S2
1845 | A64S3
1846 | A64S4
1847 | A64S5
1848 | A64S6
1849 | A64S7
1850 | A64S8
1851 | A64S9
1852 | A64S10
1853 | A64S11
1854 | A64S12
1855 | A64S13
1856 | A64S14
1857 | A64S15
1858 | A64S16
1859 | A64S17
1860 | A64S18
1861 | A64S19
1862 | A64S20
1863 | A64S21
1864 | A64S22
1865 | A64S23
1866 | A64S24
1867 | A64S25
1868 | A64S26
1869 | A64S27
1870 | A64S28
1871 | A64S29
1872 | A64S30
1873 | A64S31
1874 | A64H0
1875 | A64H1
1876 | A64H2
1877 | A64H3
1878 | A64H4
1879 | A64H5
1880 | A64H6
1881 | A64H7
1882 | A64H8
1883 | A64H9
1884 | A64H10
1885 | A64H11
1886 | A64H12
1887 | A64H13
1888 | A64H14
1889 | A64H15
1890 | A64H16
1891 | A64H17
1892 | A64H18
1893 | A64H19
1894 | A64H20
1895 | A64H21
1896 | A64H22
1897 | A64H23
1898 | A64H24
1899 | A64H25
1900 | A64H26
1901 | A64H27
1902 | A64H28
1903 | A64H29
1904 | A64H30
1905 | A64H31
1906 | A64B0
1907 | A64B1
1908 | A64B2
1909 | A64B3
1910 | A64B4
1911 | A64B5
1912 | A64B6
1913 | A64B7
1914 | A64B8
1915 | A64B9
1916 | A64B10
1917 | A64B11
1918 | A64B12
1919 | A64B13
1920 | A64B14
1921 | A64B15
1922 | A64B16
1923 | A64B17
1924 | A64B18
1925 | A64B19
1926 | A64B20
1927 | A64B21
1928 | A64B22
1929 | A64B23
1930 | A64B24
1931 | A64B25
1932 | A64B26
1933 | A64B27
1934 | A64B28
1935 | A64B29
1936 | A64B30
1937 | A64B31
1938 | A64Z0
1939 | A64Z1
1940 | A64Z2
1941 | A64Z3
1942 | A64Z4
1943 | A64Z5
1944 | A64Z6
1945 | A64Z7
1946 | A64Z8
1947 | A64Z9
1948 | A64Z10
1949 | A64Z11
1950 | A64Z12
1951 | A64Z13
1952 | A64Z14
1953 | A64Z15
1954 | A64Z16
1955 | A64Z17
1956 | A64Z18
1957 | A64Z19
1958 | A64Z20
1959 | A64Z21
1960 | A64Z22
1961 | A64Z23
1962 | A64Z24
1963 | A64Z25
1964 | A64Z26
1965 | A64Z27
1966 | A64Z28
1967 | A64Z29
1968 | A64Z30
1969 | A64Z31
1970 | A64P0
1971 | A64P1
1972 | A64P2
1973 | A64P3
1974 | A64P4
1975 | A64P5
1976 | A64P6
1977 | A64P7
1978 | A64P8
1979 | A64P9
1980 | A64P10
1981 | A64P11
1982 | A64P12
1983 | A64P13
1984 | A64P14
1985 | A64P15
1986 )
1987 }
1988
1989 #[must_use]
1991 pub fn a64_reg_num(self) -> u8 {
1992 use Register::*;
1993 match self {
1994 A64X0 | A64W0 => 0,
1995 A64X1 | A64W1 => 1,
1996 A64X2 | A64W2 => 2,
1997 A64X3 | A64W3 => 3,
1998 A64X4 | A64W4 => 4,
1999 A64X5 | A64W5 => 5,
2000 A64X6 | A64W6 => 6,
2001 A64X7 | A64W7 => 7,
2002 A64X8 | A64W8 => 8,
2003 A64X9 | A64W9 => 9,
2004 A64X10 | A64W10 => 10,
2005 A64X11 | A64W11 => 11,
2006 A64X12 | A64W12 => 12,
2007 A64X13 | A64W13 => 13,
2008 A64X14 | A64W14 => 14,
2009 A64X15 | A64W15 => 15,
2010 A64X16 | A64W16 => 16,
2011 A64X17 | A64W17 => 17,
2012 A64X18 | A64W18 => 18,
2013 A64X19 | A64W19 => 19,
2014 A64X20 | A64W20 => 20,
2015 A64X21 | A64W21 => 21,
2016 A64X22 | A64W22 => 22,
2017 A64X23 | A64W23 => 23,
2018 A64X24 | A64W24 => 24,
2019 A64X25 | A64W25 => 25,
2020 A64X26 | A64W26 => 26,
2021 A64X27 | A64W27 => 27,
2022 A64X28 | A64W28 => 28,
2023 A64X29 | A64W29 => 29,
2024 A64X30 | A64W30 => 30,
2025 A64Sp | A64Xzr | A64Wzr => 31,
2026 A64V0 | A64Q0 | A64D0 | A64S0 | A64H0 | A64B0 => 0,
2028 A64V1 | A64Q1 | A64D1 | A64S1 | A64H1 | A64B1 => 1,
2029 A64V2 | A64Q2 | A64D2 | A64S2 | A64H2 | A64B2 => 2,
2030 A64V3 | A64Q3 | A64D3 | A64S3 | A64H3 | A64B3 => 3,
2031 A64V4 | A64Q4 | A64D4 | A64S4 | A64H4 | A64B4 => 4,
2032 A64V5 | A64Q5 | A64D5 | A64S5 | A64H5 | A64B5 => 5,
2033 A64V6 | A64Q6 | A64D6 | A64S6 | A64H6 | A64B6 => 6,
2034 A64V7 | A64Q7 | A64D7 | A64S7 | A64H7 | A64B7 => 7,
2035 A64V8 | A64Q8 | A64D8 | A64S8 | A64H8 | A64B8 => 8,
2036 A64V9 | A64Q9 | A64D9 | A64S9 | A64H9 | A64B9 => 9,
2037 A64V10 | A64Q10 | A64D10 | A64S10 | A64H10 | A64B10 => 10,
2038 A64V11 | A64Q11 | A64D11 | A64S11 | A64H11 | A64B11 => 11,
2039 A64V12 | A64Q12 | A64D12 | A64S12 | A64H12 | A64B12 => 12,
2040 A64V13 | A64Q13 | A64D13 | A64S13 | A64H13 | A64B13 => 13,
2041 A64V14 | A64Q14 | A64D14 | A64S14 | A64H14 | A64B14 => 14,
2042 A64V15 | A64Q15 | A64D15 | A64S15 | A64H15 | A64B15 => 15,
2043 A64V16 | A64Q16 | A64D16 | A64S16 | A64H16 | A64B16 => 16,
2044 A64V17 | A64Q17 | A64D17 | A64S17 | A64H17 | A64B17 => 17,
2045 A64V18 | A64Q18 | A64D18 | A64S18 | A64H18 | A64B18 => 18,
2046 A64V19 | A64Q19 | A64D19 | A64S19 | A64H19 | A64B19 => 19,
2047 A64V20 | A64Q20 | A64D20 | A64S20 | A64H20 | A64B20 => 20,
2048 A64V21 | A64Q21 | A64D21 | A64S21 | A64H21 | A64B21 => 21,
2049 A64V22 | A64Q22 | A64D22 | A64S22 | A64H22 | A64B22 => 22,
2050 A64V23 | A64Q23 | A64D23 | A64S23 | A64H23 | A64B23 => 23,
2051 A64V24 | A64Q24 | A64D24 | A64S24 | A64H24 | A64B24 => 24,
2052 A64V25 | A64Q25 | A64D25 | A64S25 | A64H25 | A64B25 => 25,
2053 A64V26 | A64Q26 | A64D26 | A64S26 | A64H26 | A64B26 => 26,
2054 A64V27 | A64Q27 | A64D27 | A64S27 | A64H27 | A64B27 => 27,
2055 A64V28 | A64Q28 | A64D28 | A64S28 | A64H28 | A64B28 => 28,
2056 A64V29 | A64Q29 | A64D29 | A64S29 | A64H29 | A64B29 => 29,
2057 A64V30 | A64Q30 | A64D30 | A64S30 | A64H30 | A64B30 => 30,
2058 A64V31 | A64Q31 | A64D31 | A64S31 | A64H31 | A64B31 => 31,
2059 A64Z0 => 0,
2061 A64Z1 => 1,
2062 A64Z2 => 2,
2063 A64Z3 => 3,
2064 A64Z4 => 4,
2065 A64Z5 => 5,
2066 A64Z6 => 6,
2067 A64Z7 => 7,
2068 A64Z8 => 8,
2069 A64Z9 => 9,
2070 A64Z10 => 10,
2071 A64Z11 => 11,
2072 A64Z12 => 12,
2073 A64Z13 => 13,
2074 A64Z14 => 14,
2075 A64Z15 => 15,
2076 A64Z16 => 16,
2077 A64Z17 => 17,
2078 A64Z18 => 18,
2079 A64Z19 => 19,
2080 A64Z20 => 20,
2081 A64Z21 => 21,
2082 A64Z22 => 22,
2083 A64Z23 => 23,
2084 A64Z24 => 24,
2085 A64Z25 => 25,
2086 A64Z26 => 26,
2087 A64Z27 => 27,
2088 A64Z28 => 28,
2089 A64Z29 => 29,
2090 A64Z30 => 30,
2091 A64Z31 => 31,
2092 _ => 0,
2093 }
2094 }
2095
2096 #[must_use]
2100 pub fn is_a64_vector(self) -> bool {
2101 use Register::*;
2102 matches!(
2103 self,
2104 A64V0
2105 | A64V1
2106 | A64V2
2107 | A64V3
2108 | A64V4
2109 | A64V5
2110 | A64V6
2111 | A64V7
2112 | A64V8
2113 | A64V9
2114 | A64V10
2115 | A64V11
2116 | A64V12
2117 | A64V13
2118 | A64V14
2119 | A64V15
2120 | A64V16
2121 | A64V17
2122 | A64V18
2123 | A64V19
2124 | A64V20
2125 | A64V21
2126 | A64V22
2127 | A64V23
2128 | A64V24
2129 | A64V25
2130 | A64V26
2131 | A64V27
2132 | A64V28
2133 | A64V29
2134 | A64V30
2135 | A64V31
2136 )
2137 }
2138
2139 #[must_use]
2141 pub fn is_a64_simd_fp(self) -> bool {
2142 use Register::*;
2143 matches!(
2144 self,
2145 A64V0
2146 | A64V1
2147 | A64V2
2148 | A64V3
2149 | A64V4
2150 | A64V5
2151 | A64V6
2152 | A64V7
2153 | A64V8
2154 | A64V9
2155 | A64V10
2156 | A64V11
2157 | A64V12
2158 | A64V13
2159 | A64V14
2160 | A64V15
2161 | A64V16
2162 | A64V17
2163 | A64V18
2164 | A64V19
2165 | A64V20
2166 | A64V21
2167 | A64V22
2168 | A64V23
2169 | A64V24
2170 | A64V25
2171 | A64V26
2172 | A64V27
2173 | A64V28
2174 | A64V29
2175 | A64V30
2176 | A64V31
2177 | A64Q0
2178 | A64Q1
2179 | A64Q2
2180 | A64Q3
2181 | A64Q4
2182 | A64Q5
2183 | A64Q6
2184 | A64Q7
2185 | A64Q8
2186 | A64Q9
2187 | A64Q10
2188 | A64Q11
2189 | A64Q12
2190 | A64Q13
2191 | A64Q14
2192 | A64Q15
2193 | A64Q16
2194 | A64Q17
2195 | A64Q18
2196 | A64Q19
2197 | A64Q20
2198 | A64Q21
2199 | A64Q22
2200 | A64Q23
2201 | A64Q24
2202 | A64Q25
2203 | A64Q26
2204 | A64Q27
2205 | A64Q28
2206 | A64Q29
2207 | A64Q30
2208 | A64Q31
2209 | A64D0
2210 | A64D1
2211 | A64D2
2212 | A64D3
2213 | A64D4
2214 | A64D5
2215 | A64D6
2216 | A64D7
2217 | A64D8
2218 | A64D9
2219 | A64D10
2220 | A64D11
2221 | A64D12
2222 | A64D13
2223 | A64D14
2224 | A64D15
2225 | A64D16
2226 | A64D17
2227 | A64D18
2228 | A64D19
2229 | A64D20
2230 | A64D21
2231 | A64D22
2232 | A64D23
2233 | A64D24
2234 | A64D25
2235 | A64D26
2236 | A64D27
2237 | A64D28
2238 | A64D29
2239 | A64D30
2240 | A64D31
2241 | A64S0
2242 | A64S1
2243 | A64S2
2244 | A64S3
2245 | A64S4
2246 | A64S5
2247 | A64S6
2248 | A64S7
2249 | A64S8
2250 | A64S9
2251 | A64S10
2252 | A64S11
2253 | A64S12
2254 | A64S13
2255 | A64S14
2256 | A64S15
2257 | A64S16
2258 | A64S17
2259 | A64S18
2260 | A64S19
2261 | A64S20
2262 | A64S21
2263 | A64S22
2264 | A64S23
2265 | A64S24
2266 | A64S25
2267 | A64S26
2268 | A64S27
2269 | A64S28
2270 | A64S29
2271 | A64S30
2272 | A64S31
2273 | A64H0
2274 | A64H1
2275 | A64H2
2276 | A64H3
2277 | A64H4
2278 | A64H5
2279 | A64H6
2280 | A64H7
2281 | A64H8
2282 | A64H9
2283 | A64H10
2284 | A64H11
2285 | A64H12
2286 | A64H13
2287 | A64H14
2288 | A64H15
2289 | A64H16
2290 | A64H17
2291 | A64H18
2292 | A64H19
2293 | A64H20
2294 | A64H21
2295 | A64H22
2296 | A64H23
2297 | A64H24
2298 | A64H25
2299 | A64H26
2300 | A64H27
2301 | A64H28
2302 | A64H29
2303 | A64H30
2304 | A64H31
2305 | A64B0
2306 | A64B1
2307 | A64B2
2308 | A64B3
2309 | A64B4
2310 | A64B5
2311 | A64B6
2312 | A64B7
2313 | A64B8
2314 | A64B9
2315 | A64B10
2316 | A64B11
2317 | A64B12
2318 | A64B13
2319 | A64B14
2320 | A64B15
2321 | A64B16
2322 | A64B17
2323 | A64B18
2324 | A64B19
2325 | A64B20
2326 | A64B21
2327 | A64B22
2328 | A64B23
2329 | A64B24
2330 | A64B25
2331 | A64B26
2332 | A64B27
2333 | A64B28
2334 | A64B29
2335 | A64B30
2336 | A64B31
2337 )
2338 }
2339
2340 #[must_use]
2342 pub fn a64_simd_fp_bits(self) -> u32 {
2343 use Register::*;
2344 match self {
2345 A64V0 | A64V1 | A64V2 | A64V3 | A64V4 | A64V5 | A64V6 | A64V7 | A64V8 | A64V9
2346 | A64V10 | A64V11 | A64V12 | A64V13 | A64V14 | A64V15 | A64V16 | A64V17 | A64V18
2347 | A64V19 | A64V20 | A64V21 | A64V22 | A64V23 | A64V24 | A64V25 | A64V26 | A64V27
2348 | A64V28 | A64V29 | A64V30 | A64V31 | A64Q0 | A64Q1 | A64Q2 | A64Q3 | A64Q4 | A64Q5
2349 | A64Q6 | A64Q7 | A64Q8 | A64Q9 | A64Q10 | A64Q11 | A64Q12 | A64Q13 | A64Q14
2350 | A64Q15 | A64Q16 | A64Q17 | A64Q18 | A64Q19 | A64Q20 | A64Q21 | A64Q22 | A64Q23
2351 | A64Q24 | A64Q25 | A64Q26 | A64Q27 | A64Q28 | A64Q29 | A64Q30 | A64Q31 => 128,
2352 A64D0 | A64D1 | A64D2 | A64D3 | A64D4 | A64D5 | A64D6 | A64D7 | A64D8 | A64D9
2353 | A64D10 | A64D11 | A64D12 | A64D13 | A64D14 | A64D15 | A64D16 | A64D17 | A64D18
2354 | A64D19 | A64D20 | A64D21 | A64D22 | A64D23 | A64D24 | A64D25 | A64D26 | A64D27
2355 | A64D28 | A64D29 | A64D30 | A64D31 => 64,
2356 A64S0 | A64S1 | A64S2 | A64S3 | A64S4 | A64S5 | A64S6 | A64S7 | A64S8 | A64S9
2357 | A64S10 | A64S11 | A64S12 | A64S13 | A64S14 | A64S15 | A64S16 | A64S17 | A64S18
2358 | A64S19 | A64S20 | A64S21 | A64S22 | A64S23 | A64S24 | A64S25 | A64S26 | A64S27
2359 | A64S28 | A64S29 | A64S30 | A64S31 => 32,
2360 A64H0 | A64H1 | A64H2 | A64H3 | A64H4 | A64H5 | A64H6 | A64H7 | A64H8 | A64H9
2361 | A64H10 | A64H11 | A64H12 | A64H13 | A64H14 | A64H15 | A64H16 | A64H17 | A64H18
2362 | A64H19 | A64H20 | A64H21 | A64H22 | A64H23 | A64H24 | A64H25 | A64H26 | A64H27
2363 | A64H28 | A64H29 | A64H30 | A64H31 => 16,
2364 A64B0 | A64B1 | A64B2 | A64B3 | A64B4 | A64B5 | A64B6 | A64B7 | A64B8 | A64B9
2365 | A64B10 | A64B11 | A64B12 | A64B13 | A64B14 | A64B15 | A64B16 | A64B17 | A64B18
2366 | A64B19 | A64B20 | A64B21 | A64B22 | A64B23 | A64B24 | A64B25 | A64B26 | A64B27
2367 | A64B28 | A64B29 | A64B30 | A64B31 => 8,
2368 _ => 0,
2369 }
2370 }
2371
2372 #[must_use]
2374 pub fn is_a64_64bit(self) -> bool {
2375 use Register::*;
2376 matches!(
2377 self,
2378 A64X0
2379 | A64X1
2380 | A64X2
2381 | A64X3
2382 | A64X4
2383 | A64X5
2384 | A64X6
2385 | A64X7
2386 | A64X8
2387 | A64X9
2388 | A64X10
2389 | A64X11
2390 | A64X12
2391 | A64X13
2392 | A64X14
2393 | A64X15
2394 | A64X16
2395 | A64X17
2396 | A64X18
2397 | A64X19
2398 | A64X20
2399 | A64X21
2400 | A64X22
2401 | A64X23
2402 | A64X24
2403 | A64X25
2404 | A64X26
2405 | A64X27
2406 | A64X28
2407 | A64X29
2408 | A64X30
2409 | A64Sp
2410 | A64Xzr
2411 )
2412 }
2413
2414 #[must_use]
2416 pub fn is_riscv(self) -> bool {
2417 use Register::*;
2418 matches!(
2419 self,
2420 RvX0 | RvX1
2421 | RvX2
2422 | RvX3
2423 | RvX4
2424 | RvX5
2425 | RvX6
2426 | RvX7
2427 | RvX8
2428 | RvX9
2429 | RvX10
2430 | RvX11
2431 | RvX12
2432 | RvX13
2433 | RvX14
2434 | RvX15
2435 | RvX16
2436 | RvX17
2437 | RvX18
2438 | RvX19
2439 | RvX20
2440 | RvX21
2441 | RvX22
2442 | RvX23
2443 | RvX24
2444 | RvX25
2445 | RvX26
2446 | RvX27
2447 | RvX28
2448 | RvX29
2449 | RvX30
2450 | RvX31
2451 )
2452 }
2453
2454 #[must_use]
2456 pub fn rv_reg_num(self) -> u8 {
2457 use Register::*;
2458 match self {
2459 RvX0 => 0,
2460 RvX1 => 1,
2461 RvX2 => 2,
2462 RvX3 => 3,
2463 RvX4 => 4,
2464 RvX5 => 5,
2465 RvX6 => 6,
2466 RvX7 => 7,
2467 RvX8 => 8,
2468 RvX9 => 9,
2469 RvX10 => 10,
2470 RvX11 => 11,
2471 RvX12 => 12,
2472 RvX13 => 13,
2473 RvX14 => 14,
2474 RvX15 => 15,
2475 RvX16 => 16,
2476 RvX17 => 17,
2477 RvX18 => 18,
2478 RvX19 => 19,
2479 RvX20 => 20,
2480 RvX21 => 21,
2481 RvX22 => 22,
2482 RvX23 => 23,
2483 RvX24 => 24,
2484 RvX25 => 25,
2485 RvX26 => 26,
2486 RvX27 => 27,
2487 RvX28 => 28,
2488 RvX29 => 29,
2489 RvX30 => 30,
2490 RvX31 => 31,
2491 _ => 0,
2492 }
2493 }
2494
2495 #[must_use]
2497 pub fn is_riscv_fp(self) -> bool {
2498 use Register::*;
2499 matches!(
2500 self,
2501 RvF0 | RvF1
2502 | RvF2
2503 | RvF3
2504 | RvF4
2505 | RvF5
2506 | RvF6
2507 | RvF7
2508 | RvF8
2509 | RvF9
2510 | RvF10
2511 | RvF11
2512 | RvF12
2513 | RvF13
2514 | RvF14
2515 | RvF15
2516 | RvF16
2517 | RvF17
2518 | RvF18
2519 | RvF19
2520 | RvF20
2521 | RvF21
2522 | RvF22
2523 | RvF23
2524 | RvF24
2525 | RvF25
2526 | RvF26
2527 | RvF27
2528 | RvF28
2529 | RvF29
2530 | RvF30
2531 | RvF31
2532 )
2533 }
2534
2535 #[must_use]
2537 pub fn rv_fp_reg_num(self) -> u8 {
2538 use Register::*;
2539 match self {
2540 RvF0 => 0,
2541 RvF1 => 1,
2542 RvF2 => 2,
2543 RvF3 => 3,
2544 RvF4 => 4,
2545 RvF5 => 5,
2546 RvF6 => 6,
2547 RvF7 => 7,
2548 RvF8 => 8,
2549 RvF9 => 9,
2550 RvF10 => 10,
2551 RvF11 => 11,
2552 RvF12 => 12,
2553 RvF13 => 13,
2554 RvF14 => 14,
2555 RvF15 => 15,
2556 RvF16 => 16,
2557 RvF17 => 17,
2558 RvF18 => 18,
2559 RvF19 => 19,
2560 RvF20 => 20,
2561 RvF21 => 21,
2562 RvF22 => 22,
2563 RvF23 => 23,
2564 RvF24 => 24,
2565 RvF25 => 25,
2566 RvF26 => 26,
2567 RvF27 => 27,
2568 RvF28 => 28,
2569 RvF29 => 29,
2570 RvF30 => 30,
2571 RvF31 => 31,
2572 _ => 0,
2573 }
2574 }
2575
2576 #[must_use]
2578 pub fn is_a64_sve_z(self) -> bool {
2579 use Register::*;
2580 matches!(
2581 self,
2582 A64Z0
2583 | A64Z1
2584 | A64Z2
2585 | A64Z3
2586 | A64Z4
2587 | A64Z5
2588 | A64Z6
2589 | A64Z7
2590 | A64Z8
2591 | A64Z9
2592 | A64Z10
2593 | A64Z11
2594 | A64Z12
2595 | A64Z13
2596 | A64Z14
2597 | A64Z15
2598 | A64Z16
2599 | A64Z17
2600 | A64Z18
2601 | A64Z19
2602 | A64Z20
2603 | A64Z21
2604 | A64Z22
2605 | A64Z23
2606 | A64Z24
2607 | A64Z25
2608 | A64Z26
2609 | A64Z27
2610 | A64Z28
2611 | A64Z29
2612 | A64Z30
2613 | A64Z31
2614 )
2615 }
2616
2617 #[must_use]
2619 pub fn is_a64_sve_p(self) -> bool {
2620 use Register::*;
2621 matches!(
2622 self,
2623 A64P0
2624 | A64P1
2625 | A64P2
2626 | A64P3
2627 | A64P4
2628 | A64P5
2629 | A64P6
2630 | A64P7
2631 | A64P8
2632 | A64P9
2633 | A64P10
2634 | A64P11
2635 | A64P12
2636 | A64P13
2637 | A64P14
2638 | A64P15
2639 )
2640 }
2641
2642 #[must_use]
2644 pub fn a64_p_num(self) -> u8 {
2645 use Register::*;
2646 match self {
2647 A64P0 => 0,
2648 A64P1 => 1,
2649 A64P2 => 2,
2650 A64P3 => 3,
2651 A64P4 => 4,
2652 A64P5 => 5,
2653 A64P6 => 6,
2654 A64P7 => 7,
2655 A64P8 => 8,
2656 A64P9 => 9,
2657 A64P10 => 10,
2658 A64P11 => 11,
2659 A64P12 => 12,
2660 A64P13 => 13,
2661 A64P14 => 14,
2662 A64P15 => 15,
2663 _ => 0,
2664 }
2665 }
2666
2667 #[must_use]
2669 pub fn is_riscv_vec(self) -> bool {
2670 use Register::*;
2671 matches!(
2672 self,
2673 RvV0 | RvV1
2674 | RvV2
2675 | RvV3
2676 | RvV4
2677 | RvV5
2678 | RvV6
2679 | RvV7
2680 | RvV8
2681 | RvV9
2682 | RvV10
2683 | RvV11
2684 | RvV12
2685 | RvV13
2686 | RvV14
2687 | RvV15
2688 | RvV16
2689 | RvV17
2690 | RvV18
2691 | RvV19
2692 | RvV20
2693 | RvV21
2694 | RvV22
2695 | RvV23
2696 | RvV24
2697 | RvV25
2698 | RvV26
2699 | RvV27
2700 | RvV28
2701 | RvV29
2702 | RvV30
2703 | RvV31
2704 )
2705 }
2706
2707 #[must_use]
2709 pub fn rv_vec_num(self) -> u8 {
2710 use Register::*;
2711 match self {
2712 RvV0 => 0,
2713 RvV1 => 1,
2714 RvV2 => 2,
2715 RvV3 => 3,
2716 RvV4 => 4,
2717 RvV5 => 5,
2718 RvV6 => 6,
2719 RvV7 => 7,
2720 RvV8 => 8,
2721 RvV9 => 9,
2722 RvV10 => 10,
2723 RvV11 => 11,
2724 RvV12 => 12,
2725 RvV13 => 13,
2726 RvV14 => 14,
2727 RvV15 => 15,
2728 RvV16 => 16,
2729 RvV17 => 17,
2730 RvV18 => 18,
2731 RvV19 => 19,
2732 RvV20 => 20,
2733 RvV21 => 21,
2734 RvV22 => 22,
2735 RvV23 => 23,
2736 RvV24 => 24,
2737 RvV25 => 25,
2738 RvV26 => 26,
2739 RvV27 => 27,
2740 RvV28 => 28,
2741 RvV29 => 29,
2742 RvV30 => 30,
2743 RvV31 => 31,
2744 _ => 0,
2745 }
2746 }
2747}
2748
2749impl fmt::Display for Register {
2750 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2751 use fmt::Write as _;
2753 struct LowerWriter<'a, 'b>(&'a mut fmt::Formatter<'b>);
2754 impl fmt::Write for LowerWriter<'_, '_> {
2755 fn write_str(&mut self, s: &str) -> fmt::Result {
2756 for c in s.chars() {
2757 self.0.write_char(c.to_ascii_lowercase())?;
2758 }
2759 Ok(())
2760 }
2761 }
2762 write!(LowerWriter(f), "{:?}", self)
2763 }
2764}
2765
2766#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2771#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2772pub enum VectorArrangement {
2773 B8,
2775 B16,
2777 H4,
2779 H8,
2781 S2,
2783 S4,
2785 D1,
2787 D2,
2789 SveB,
2792 SveH,
2794 SveS,
2796 SveD,
2798}
2799
2800impl VectorArrangement {
2801 pub fn parse(s: &str) -> Option<Self> {
2804 let mut buf = [0u8; 4];
2806 let len = s.len().min(4);
2807 buf[..len].copy_from_slice(&s.as_bytes()[..len]);
2808 buf[..len].make_ascii_lowercase();
2809 let s = core::str::from_utf8(&buf[..len]).unwrap_or("");
2811 match s {
2812 "8b" => Some(VectorArrangement::B8),
2813 "16b" => Some(VectorArrangement::B16),
2814 "4h" => Some(VectorArrangement::H4),
2815 "8h" => Some(VectorArrangement::H8),
2816 "2s" => Some(VectorArrangement::S2),
2817 "4s" => Some(VectorArrangement::S4),
2818 "1d" => Some(VectorArrangement::D1),
2819 "2d" => Some(VectorArrangement::D2),
2820 "b" => Some(VectorArrangement::SveB),
2822 "h" => Some(VectorArrangement::SveH),
2823 "s" => Some(VectorArrangement::SveS),
2824 "d" => Some(VectorArrangement::SveD),
2825 _ => None,
2826 }
2827 }
2828
2829 pub fn element_bits(self) -> u32 {
2831 match self {
2832 VectorArrangement::B8 | VectorArrangement::B16 | VectorArrangement::SveB => 8,
2833 VectorArrangement::H4 | VectorArrangement::H8 | VectorArrangement::SveH => 16,
2834 VectorArrangement::S2 | VectorArrangement::S4 | VectorArrangement::SveS => 32,
2835 VectorArrangement::D1 | VectorArrangement::D2 | VectorArrangement::SveD => 64,
2836 }
2837 }
2838
2839 pub fn total_bits(self) -> u32 {
2841 match self {
2842 VectorArrangement::B8
2843 | VectorArrangement::H4
2844 | VectorArrangement::S2
2845 | VectorArrangement::D1 => 64,
2846 VectorArrangement::B16
2847 | VectorArrangement::H8
2848 | VectorArrangement::S4
2849 | VectorArrangement::D2 => 128,
2850 VectorArrangement::SveB
2852 | VectorArrangement::SveH
2853 | VectorArrangement::SveS
2854 | VectorArrangement::SveD => 0,
2855 }
2856 }
2857
2858 pub fn lane_count(self) -> u32 {
2860 let total = self.total_bits();
2861 if total == 0 {
2862 return 0;
2863 }
2864 total / self.element_bits()
2865 }
2866
2867 pub fn sve_size(self) -> Option<u32> {
2870 match self {
2871 VectorArrangement::SveB => Some(0),
2872 VectorArrangement::SveH => Some(1),
2873 VectorArrangement::SveS => Some(2),
2874 VectorArrangement::SveD => Some(3),
2875 _ => None,
2876 }
2877 }
2878}
2879
2880impl fmt::Display for VectorArrangement {
2881 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2882 match self {
2883 VectorArrangement::B8 => write!(f, "8B"),
2884 VectorArrangement::B16 => write!(f, "16B"),
2885 VectorArrangement::H4 => write!(f, "4H"),
2886 VectorArrangement::H8 => write!(f, "8H"),
2887 VectorArrangement::S2 => write!(f, "2S"),
2888 VectorArrangement::S4 => write!(f, "4S"),
2889 VectorArrangement::D1 => write!(f, "1D"),
2890 VectorArrangement::D2 => write!(f, "2D"),
2891 VectorArrangement::SveB => write!(f, "B"),
2892 VectorArrangement::SveH => write!(f, "H"),
2893 VectorArrangement::SveS => write!(f, "S"),
2894 VectorArrangement::SveD => write!(f, "D"),
2895 }
2896 }
2897}
2898
2899#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2901#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2902pub enum SvePredQual {
2903 Merging,
2905 Zeroing,
2907}
2908
2909impl fmt::Display for SvePredQual {
2910 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2911 match self {
2912 SvePredQual::Merging => write!(f, "/m"),
2913 SvePredQual::Zeroing => write!(f, "/z"),
2914 }
2915 }
2916}
2917
2918#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2920#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2921pub enum OperandSize {
2922 Byte,
2924 Word,
2926 Dword,
2928 Qword,
2930 Xmmword,
2932 Ymmword,
2934 Zmmword,
2936}
2937
2938impl OperandSize {
2939 pub fn bits(self) -> u16 {
2941 match self {
2942 OperandSize::Byte => 8,
2943 OperandSize::Word => 16,
2944 OperandSize::Dword => 32,
2945 OperandSize::Qword => 64,
2946 OperandSize::Xmmword => 128,
2947 OperandSize::Ymmword => 256,
2948 OperandSize::Zmmword => 512,
2949 }
2950 }
2951}
2952
2953impl fmt::Display for OperandSize {
2954 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2955 match self {
2956 OperandSize::Byte => write!(f, "byte"),
2957 OperandSize::Word => write!(f, "word"),
2958 OperandSize::Dword => write!(f, "dword"),
2959 OperandSize::Qword => write!(f, "qword"),
2960 OperandSize::Xmmword => write!(f, "xmmword"),
2961 OperandSize::Ymmword => write!(f, "ymmword"),
2962 OperandSize::Zmmword => write!(f, "zmmword"),
2963 }
2964 }
2965}
2966
2967#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
2969#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2970pub enum AddrMode {
2971 #[default]
2973 Offset,
2974 PreIndex,
2976 PostIndex,
2978}
2979
2980#[derive(Debug, Clone, PartialEq, Eq)]
2982#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2983pub struct MemoryOperand {
2984 pub size: Option<OperandSize>,
2986 pub base: Option<Register>,
2988 pub index: Option<Register>,
2990 pub scale: u8,
2992 pub disp: i64,
2994 pub segment: Option<Register>,
2996 pub disp_label: Option<String>,
2998 pub addr_mode: AddrMode,
3000 pub index_subtract: bool,
3002}
3003
3004impl Default for MemoryOperand {
3005 fn default() -> Self {
3006 Self {
3007 size: None,
3008 base: None,
3009 index: None,
3010 scale: 1,
3011 disp: 0,
3012 segment: None,
3013 disp_label: None,
3014 addr_mode: AddrMode::Offset,
3015 index_subtract: false,
3016 }
3017 }
3018}
3019
3020#[derive(Debug, Clone, PartialEq, Eq)]
3022#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3023pub enum Expr {
3024 Num(i128),
3026 Label(String),
3028 Add(Box<Expr>, Box<Expr>),
3030 Sub(Box<Expr>, Box<Expr>),
3032}
3033
3034impl Expr {
3035 pub fn eval(&self) -> Option<i128> {
3039 match self {
3040 Expr::Num(n) => Some(*n),
3041 Expr::Label(_) => None,
3042 Expr::Add(l, r) => Some(l.eval()?.checked_add(r.eval()?)?),
3043 Expr::Sub(l, r) => Some(l.eval()?.checked_sub(r.eval()?)?),
3044 }
3045 }
3046
3047 pub fn label_addend(&self) -> Option<(&str, i64)> {
3054 let mut label: Option<&str> = None;
3055 let mut addend: i64 = 0;
3056 if self.collect_single_label(&mut label, &mut addend, 1) {
3057 label.map(|l| (l, addend))
3058 } else {
3059 None
3060 }
3061 }
3062
3063 pub fn resolve_constants(&mut self, lookup: impl Fn(&str) -> Option<i128> + Copy) {
3066 match self {
3067 Expr::Label(name) => {
3068 if let Some(val) = lookup(name) {
3069 *self = Expr::Num(val);
3070 }
3071 }
3072 Expr::Add(l, r) | Expr::Sub(l, r) => {
3073 l.resolve_constants(lookup);
3074 r.resolve_constants(lookup);
3075 }
3076 Expr::Num(_) => {}
3077 }
3078 }
3079
3080 fn collect_single_label<'a>(
3083 &'a self,
3084 label: &mut Option<&'a str>,
3085 addend: &mut i64,
3086 sign: i64,
3087 ) -> bool {
3088 match self {
3089 Expr::Num(n) => {
3090 *addend = addend.wrapping_add((*n as i64).wrapping_mul(sign));
3091 true
3092 }
3093 Expr::Label(name) => {
3094 if sign != 1 || label.is_some() {
3095 false
3097 } else {
3098 *label = Some(name.as_str());
3099 true
3100 }
3101 }
3102 Expr::Add(l, r) => {
3103 l.collect_single_label(label, addend, sign)
3104 && r.collect_single_label(label, addend, sign)
3105 }
3106 Expr::Sub(l, r) => {
3107 l.collect_single_label(label, addend, sign)
3108 && r.collect_single_label(label, addend, -sign)
3109 }
3110 }
3111 }
3112}
3113
3114#[derive(Debug, Clone, PartialEq)]
3116#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3117pub enum Operand {
3118 Register(Register),
3120 Immediate(i128),
3122 Memory(Box<MemoryOperand>),
3124 Label(String),
3126 Expression(Expr),
3128 RegisterList(Vec<Register>),
3130 LiteralPoolValue(i128),
3134 VectorRegister(Register, VectorArrangement),
3137 SvePredicate(Register, SvePredQual),
3139}
3140
3141impl fmt::Display for Operand {
3142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3143 match self {
3144 Operand::Register(r) => write!(f, "{}", r),
3145 Operand::Immediate(v) => {
3146 if *v < 0 {
3147 write!(f, "-0x{:X}", v.wrapping_neg())
3148 } else {
3149 write!(f, "0x{:X}", v)
3150 }
3151 }
3152 Operand::Memory(mem) => {
3153 if let Some(sz) = mem.size {
3154 write!(f, "{} ptr ", sz)?;
3155 }
3156 write!(f, "[")?;
3157 let mut parts = false;
3158 if let Some(base) = mem.base {
3159 write!(f, "{}", base)?;
3160 parts = true;
3161 }
3162 if let Some(idx) = mem.index {
3163 if parts {
3164 write!(f, "+")?;
3165 }
3166 write!(f, "{}*{}", idx, mem.scale)?;
3167 parts = true;
3168 }
3169 if mem.disp != 0 || !parts {
3170 if parts && mem.disp >= 0 {
3171 write!(f, "+")?;
3172 }
3173 write!(f, "0x{:X}", mem.disp)?;
3174 }
3175 write!(f, "]")
3176 }
3177 Operand::Label(name) => write!(f, "{}", name),
3178 Operand::Expression(expr) => write!(f, "{}", expr),
3179 Operand::RegisterList(regs) => {
3180 write!(f, "{{")?;
3181 for (i, r) in regs.iter().enumerate() {
3182 if i > 0 {
3183 write!(f, ", ")?;
3184 }
3185 write!(f, "{}", r)?;
3186 }
3187 write!(f, "}}")
3188 }
3189 Operand::LiteralPoolValue(v) => write!(f, "={}", v),
3190 Operand::VectorRegister(r, arr) => write!(f, "{}.{}", r, arr),
3191 Operand::SvePredicate(r, qual) => write!(f, "{}{}", r, qual),
3192 }
3193 }
3194}
3195
3196impl fmt::Display for Expr {
3197 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3198 match self {
3199 Expr::Num(n) => write!(f, "{}", n),
3200 Expr::Label(name) => write!(f, "{}", name),
3201 Expr::Add(l, r) => write!(f, "({} + {})", l, r),
3202 Expr::Sub(l, r) => write!(f, "({} - {})", l, r),
3203 }
3204 }
3205}
3206
3207#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3209#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3210pub enum Prefix {
3211 Lock,
3213 Rep,
3215 Repne,
3217 SegFs,
3219 SegGs,
3221}
3222
3223impl fmt::Display for Prefix {
3224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3225 match self {
3226 Prefix::Lock => write!(f, "lock"),
3227 Prefix::Rep => write!(f, "rep"),
3228 Prefix::Repne => write!(f, "repne"),
3229 Prefix::SegFs => write!(f, "fs"),
3230 Prefix::SegGs => write!(f, "gs"),
3231 }
3232 }
3233}
3234
3235#[derive(Clone, Copy)]
3243pub struct Mnemonic {
3244 buf: [u8; 24],
3245 len: u8,
3246}
3247
3248impl Mnemonic {
3249 pub const MAX_LEN: usize = 24;
3251
3252 #[inline]
3254 pub const fn new() -> Self {
3255 Self {
3256 buf: [0; 24],
3257 len: 0,
3258 }
3259 }
3260
3261 #[inline]
3263 pub fn as_str(&self) -> &str {
3264 core::str::from_utf8(&self.buf[..self.len as usize]).unwrap_or("")
3266 }
3267
3268 #[inline]
3270 pub fn len(&self) -> usize {
3271 self.len as usize
3272 }
3273
3274 #[inline]
3276 pub fn is_empty(&self) -> bool {
3277 self.len == 0
3278 }
3279}
3280
3281impl From<&str> for Mnemonic {
3282 #[inline]
3283 fn from(s: &str) -> Self {
3284 let len = s.len().min(Self::MAX_LEN);
3285 let mut buf = [0u8; 24];
3286 buf[..len].copy_from_slice(&s.as_bytes()[..len]);
3287 Self {
3288 buf,
3289 len: len as u8,
3290 }
3291 }
3292}
3293
3294impl From<String> for Mnemonic {
3295 #[inline]
3296 fn from(s: String) -> Self {
3297 Self::from(s.as_str())
3298 }
3299}
3300
3301impl core::ops::Deref for Mnemonic {
3302 type Target = str;
3303 #[inline]
3304 fn deref(&self) -> &str {
3305 self.as_str()
3306 }
3307}
3308
3309impl PartialEq for Mnemonic {
3310 #[inline]
3311 fn eq(&self, other: &Self) -> bool {
3312 self.as_str() == other.as_str()
3313 }
3314}
3315
3316impl Eq for Mnemonic {}
3317
3318impl PartialEq<str> for Mnemonic {
3319 #[inline]
3320 fn eq(&self, other: &str) -> bool {
3321 self.as_str() == other
3322 }
3323}
3324
3325impl PartialEq<&str> for Mnemonic {
3326 #[inline]
3327 fn eq(&self, other: &&str) -> bool {
3328 self.as_str() == *other
3329 }
3330}
3331
3332impl PartialEq<Mnemonic> for str {
3333 #[inline]
3334 fn eq(&self, other: &Mnemonic) -> bool {
3335 self == other.as_str()
3336 }
3337}
3338
3339impl PartialEq<Mnemonic> for &str {
3340 #[inline]
3341 fn eq(&self, other: &Mnemonic) -> bool {
3342 *self == other.as_str()
3343 }
3344}
3345
3346impl PartialEq<String> for Mnemonic {
3347 #[inline]
3348 fn eq(&self, other: &String) -> bool {
3349 self.as_str() == other.as_str()
3350 }
3351}
3352
3353impl fmt::Debug for Mnemonic {
3354 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3355 write!(f, "\"{}\"", self.as_str())
3356 }
3357}
3358
3359impl fmt::Display for Mnemonic {
3360 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3361 write!(f, "{}", self.as_str())
3362 }
3363}
3364
3365impl Default for Mnemonic {
3366 fn default() -> Self {
3367 Self::new()
3368 }
3369}
3370
3371#[cfg(feature = "serde")]
3372impl serde::Serialize for Mnemonic {
3373 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3374 serializer.serialize_str(self.as_str())
3375 }
3376}
3377
3378#[cfg(feature = "serde")]
3379impl<'de> serde::Deserialize<'de> for Mnemonic {
3380 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
3381 struct V;
3382 impl<'de> serde::de::Visitor<'de> for V {
3383 type Value = Mnemonic;
3384 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3385 write!(f, "a mnemonic string (max 24 bytes)")
3386 }
3387 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Mnemonic, E> {
3388 if v.len() > Mnemonic::MAX_LEN {
3389 return Err(E::custom("mnemonic exceeds 24 bytes"));
3390 }
3391 Ok(Mnemonic::from(v))
3392 }
3393 fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Mnemonic, E> {
3394 self.visit_str(&v)
3395 }
3396 }
3397 deserializer.deserialize_str(V)
3398 }
3399}
3400
3401pub struct OperandList {
3409 items: [Operand; 6],
3410 len: u8,
3411}
3412
3413impl OperandList {
3414 pub const MAX_LEN: usize = 6;
3416
3417 #[inline]
3419 pub fn new() -> Self {
3420 Self {
3421 items: core::array::from_fn(|_| Operand::default()),
3422 len: 0,
3423 }
3424 }
3425
3426 #[inline]
3431 pub fn push(&mut self, op: Operand) {
3432 assert!(
3433 (self.len as usize) < Self::MAX_LEN,
3434 "OperandList overflow: max {} operands",
3435 Self::MAX_LEN
3436 );
3437 self.items[self.len as usize] = op;
3438 self.len += 1;
3439 }
3440
3441 #[inline]
3443 pub fn len(&self) -> usize {
3444 self.len as usize
3445 }
3446
3447 #[inline]
3449 pub fn is_empty(&self) -> bool {
3450 self.len == 0
3451 }
3452
3453 #[inline]
3455 pub fn as_slice(&self) -> &[Operand] {
3456 &self.items[..self.len as usize]
3457 }
3458
3459 #[inline]
3461 pub fn as_mut_slice(&mut self) -> &mut [Operand] {
3462 &mut self.items[..self.len as usize]
3463 }
3464}
3465
3466impl core::ops::Deref for OperandList {
3467 type Target = [Operand];
3468 #[inline]
3469 fn deref(&self) -> &[Operand] {
3470 self.as_slice()
3471 }
3472}
3473
3474impl core::ops::DerefMut for OperandList {
3475 #[inline]
3476 fn deref_mut(&mut self) -> &mut [Operand] {
3477 self.as_mut_slice()
3478 }
3479}
3480
3481impl Clone for OperandList {
3482 fn clone(&self) -> Self {
3483 let mut items: [Operand; 6] = core::array::from_fn(|_| Operand::default());
3484 for (i, op) in self.items[..self.len as usize].iter().enumerate() {
3485 items[i] = op.clone();
3486 }
3487 Self {
3488 items,
3489 len: self.len,
3490 }
3491 }
3492}
3493
3494impl PartialEq for OperandList {
3495 fn eq(&self, other: &Self) -> bool {
3496 self.as_slice() == other.as_slice()
3497 }
3498}
3499
3500impl PartialEq<Vec<Operand>> for OperandList {
3501 fn eq(&self, other: &Vec<Operand>) -> bool {
3502 self.as_slice() == &other[..]
3503 }
3504}
3505
3506impl fmt::Debug for OperandList {
3507 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3508 f.debug_list().entries(self.as_slice().iter()).finish()
3509 }
3510}
3511
3512impl Default for OperandList {
3513 fn default() -> Self {
3514 Self::new()
3515 }
3516}
3517
3518impl From<Vec<Operand>> for OperandList {
3519 fn from(v: Vec<Operand>) -> Self {
3520 assert!(
3521 v.len() <= Self::MAX_LEN,
3522 "OperandList: max {} operands, got {}",
3523 Self::MAX_LEN,
3524 v.len()
3525 );
3526 let mut list = Self::new();
3527 for op in v {
3528 list.push(op);
3529 }
3530 list
3531 }
3532}
3533
3534impl<'a> IntoIterator for &'a OperandList {
3535 type Item = &'a Operand;
3536 type IntoIter = core::slice::Iter<'a, Operand>;
3537 fn into_iter(self) -> Self::IntoIter {
3538 self.as_slice().iter()
3539 }
3540}
3541
3542impl<'a> IntoIterator for &'a mut OperandList {
3543 type Item = &'a mut Operand;
3544 type IntoIter = core::slice::IterMut<'a, Operand>;
3545 fn into_iter(self) -> Self::IntoIter {
3546 self.as_mut_slice().iter_mut()
3547 }
3548}
3549
3550#[cfg(feature = "serde")]
3551impl serde::Serialize for OperandList {
3552 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3553 use serde::ser::SerializeSeq;
3554 let mut seq = serializer.serialize_seq(Some(self.len()))?;
3555 for op in self.as_slice() {
3556 seq.serialize_element(op)?;
3557 }
3558 seq.end()
3559 }
3560}
3561
3562#[cfg(feature = "serde")]
3563impl<'de> serde::Deserialize<'de> for OperandList {
3564 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
3565 let v: Vec<Operand> = Vec::deserialize(deserializer)?;
3566 if v.len() > Self::MAX_LEN {
3567 return Err(serde::de::Error::custom(alloc::format!(
3568 "too many operands: {} > {}",
3569 v.len(),
3570 Self::MAX_LEN
3571 )));
3572 }
3573 Ok(Self::from(v))
3574 }
3575}
3576
3577#[derive(Clone, Copy)]
3584pub struct PrefixList {
3585 items: [Prefix; 4],
3586 len: u8,
3587}
3588
3589impl PrefixList {
3590 pub const MAX_LEN: usize = 4;
3592
3593 #[inline]
3595 pub const fn new() -> Self {
3596 Self {
3597 items: [Prefix::Lock; 4], len: 0,
3599 }
3600 }
3601
3602 #[inline]
3607 pub fn push(&mut self, p: Prefix) {
3608 assert!(
3609 (self.len as usize) < Self::MAX_LEN,
3610 "PrefixList overflow: max {} prefixes",
3611 Self::MAX_LEN
3612 );
3613 self.items[self.len as usize] = p;
3614 self.len += 1;
3615 }
3616
3617 #[inline]
3619 pub fn len(&self) -> usize {
3620 self.len as usize
3621 }
3622
3623 #[inline]
3625 pub fn is_empty(&self) -> bool {
3626 self.len == 0
3627 }
3628
3629 #[inline]
3631 pub fn as_slice(&self) -> &[Prefix] {
3632 &self.items[..self.len as usize]
3633 }
3634}
3635
3636impl core::ops::Deref for PrefixList {
3637 type Target = [Prefix];
3638 #[inline]
3639 fn deref(&self) -> &[Prefix] {
3640 self.as_slice()
3641 }
3642}
3643
3644impl PartialEq for PrefixList {
3645 fn eq(&self, other: &Self) -> bool {
3646 self.as_slice() == other.as_slice()
3647 }
3648}
3649
3650impl Eq for PrefixList {}
3651
3652impl PartialEq<Vec<Prefix>> for PrefixList {
3653 fn eq(&self, other: &Vec<Prefix>) -> bool {
3654 self.as_slice() == &other[..]
3655 }
3656}
3657
3658impl fmt::Debug for PrefixList {
3659 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3660 f.debug_list().entries(self.as_slice().iter()).finish()
3661 }
3662}
3663
3664impl Default for PrefixList {
3665 fn default() -> Self {
3666 Self::new()
3667 }
3668}
3669
3670impl From<Vec<Prefix>> for PrefixList {
3671 fn from(v: Vec<Prefix>) -> Self {
3672 assert!(
3673 v.len() <= Self::MAX_LEN,
3674 "PrefixList: max {} prefixes, got {}",
3675 Self::MAX_LEN,
3676 v.len()
3677 );
3678 let mut list = Self::new();
3679 for p in v {
3680 list.push(p);
3681 }
3682 list
3683 }
3684}
3685
3686impl<'a> IntoIterator for &'a PrefixList {
3687 type Item = &'a Prefix;
3688 type IntoIter = core::slice::Iter<'a, Prefix>;
3689 fn into_iter(self) -> Self::IntoIter {
3690 self.as_slice().iter()
3691 }
3692}
3693
3694#[cfg(feature = "serde")]
3695impl serde::Serialize for PrefixList {
3696 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3697 use serde::ser::SerializeSeq;
3698 let mut seq = serializer.serialize_seq(Some(self.len()))?;
3699 for p in self.as_slice() {
3700 seq.serialize_element(p)?;
3701 }
3702 seq.end()
3703 }
3704}
3705
3706#[cfg(feature = "serde")]
3707impl<'de> serde::Deserialize<'de> for PrefixList {
3708 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
3709 let v: Vec<Prefix> = Vec::deserialize(deserializer)?;
3710 if v.len() > Self::MAX_LEN {
3711 return Err(serde::de::Error::custom(alloc::format!(
3712 "too many prefixes: {} > {}",
3713 v.len(),
3714 Self::MAX_LEN
3715 )));
3716 }
3717 Ok(Self::from(v))
3718 }
3719}
3720
3721impl Default for Operand {
3724 #[inline]
3727 fn default() -> Self {
3728 Operand::Immediate(0)
3729 }
3730}
3731
3732#[derive(Debug, Clone, PartialEq)]
3734#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3735pub struct Instruction {
3736 pub mnemonic: Mnemonic,
3738 pub operands: OperandList,
3740 pub size_hint: Option<OperandSize>,
3742 pub prefixes: PrefixList,
3744 pub opmask: Option<Register>,
3746 pub zeroing: bool,
3748 pub broadcast: Option<BroadcastMode>,
3750 pub span: Span,
3752}
3753
3754#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3756#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3757pub enum BroadcastMode {
3758 OneToTwo,
3760 OneToFour,
3762 OneToEight,
3764 OneToSixteen,
3766}
3767
3768#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3770#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3771pub enum DataSize {
3772 Byte,
3774 Word,
3776 Long,
3778 Quad,
3780}
3781
3782impl fmt::Display for DataSize {
3783 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3784 match self {
3785 DataSize::Byte => write!(f, ".byte"),
3786 DataSize::Word => write!(f, ".word"),
3787 DataSize::Long => write!(f, ".long"),
3788 DataSize::Quad => write!(f, ".quad"),
3789 }
3790 }
3791}
3792
3793#[derive(Debug, Clone, PartialEq)]
3795#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3796pub enum DataValue {
3797 Integer(i128),
3799 Label(String, i64),
3801 Bytes(Vec<u8>),
3803}
3804
3805#[derive(Debug, Clone, PartialEq)]
3807#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3808pub struct DataDecl {
3809 pub size: DataSize,
3811 pub values: Vec<DataValue>,
3813 pub span: Span,
3815}
3816
3817#[derive(Debug, Clone, PartialEq, Eq)]
3819#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3820pub struct AlignDirective {
3821 pub alignment: u32,
3823 pub fill: Option<u8>,
3825 pub max_skip: Option<u32>,
3827 pub span: Span,
3829}
3830
3831#[derive(Debug, Clone, PartialEq)]
3833#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3834pub struct ConstDef {
3835 pub name: String,
3837 pub value: i128,
3839 pub span: Span,
3841}
3842
3843#[derive(Debug, Clone, PartialEq, Eq)]
3845#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3846pub struct FillDirective {
3847 pub count: u32,
3849 pub size: u8,
3851 pub value: i64,
3853 pub span: Span,
3855}
3856
3857#[derive(Debug, Clone, PartialEq, Eq)]
3859#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3860pub struct SpaceDirective {
3861 pub size: u32,
3863 pub fill: u8,
3865 pub span: Span,
3867}
3868
3869#[derive(Debug, Clone, PartialEq, Eq)]
3871#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3872pub struct OrgDirective {
3873 pub offset: u64,
3875 pub fill: u8,
3877 pub span: Span,
3879}
3880
3881#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3886#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3887pub enum X86Mode {
3888 Mode16,
3890 Mode32,
3892 Mode64,
3894}
3895
3896#[derive(Debug, Clone, PartialEq)]
3898#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3899#[allow(clippy::large_enum_variant)] pub enum Statement {
3901 Label(String, Span),
3903 Instruction(Instruction),
3905 Data(DataDecl),
3907 Align(AlignDirective),
3909 Const(ConstDef),
3911 Fill(FillDirective),
3913 Space(SpaceDirective),
3915 Org(OrgDirective),
3917 CodeMode(X86Mode, Span),
3919 Ltorg(Span),
3921 OptionRvc(bool, Span),
3923 ThumbMode(bool, Span),
3925 ThumbFunc(Span),
3927}
3928
3929#[cfg(test)]
3930mod tests {
3931 use super::*;
3932
3933 #[test]
3934 fn register_size_bits() {
3935 assert_eq!(Register::Rax.size_bits(), 64);
3936 assert_eq!(Register::Eax.size_bits(), 32);
3937 assert_eq!(Register::Ax.size_bits(), 16);
3938 assert_eq!(Register::Al.size_bits(), 8);
3939 assert_eq!(Register::R8.size_bits(), 64);
3940 assert_eq!(Register::R8d.size_bits(), 32);
3941 }
3942
3943 #[test]
3944 fn register_base_code() {
3945 assert_eq!(Register::Rax.base_code(), 0);
3946 assert_eq!(Register::Rcx.base_code(), 1);
3947 assert_eq!(Register::Rdx.base_code(), 2);
3948 assert_eq!(Register::Rbx.base_code(), 3);
3949 assert_eq!(Register::Rsp.base_code(), 4);
3950 assert_eq!(Register::Rbp.base_code(), 5);
3951 assert_eq!(Register::Rsi.base_code(), 6);
3952 assert_eq!(Register::Rdi.base_code(), 7);
3953 }
3954
3955 #[test]
3956 fn register_is_extended() {
3957 assert!(!Register::Rax.is_extended());
3958 assert!(Register::R8.is_extended());
3959 assert!(Register::R15d.is_extended());
3960 assert!(Register::R8b.is_extended());
3961 }
3962
3963 #[test]
3964 fn register_high_byte() {
3965 assert!(Register::Ah.is_high_byte());
3966 assert!(Register::Ch.is_high_byte());
3967 assert!(!Register::Al.is_high_byte());
3968 assert!(!Register::Spl.is_high_byte());
3969 }
3970
3971 #[test]
3972 fn arch_display() {
3973 assert_eq!(format!("{}", Arch::X86_64), "x86_64");
3974 assert_eq!(format!("{}", Arch::Aarch64), "AArch64");
3975 }
3976
3977 #[test]
3978 fn operand_size_bits() {
3979 assert_eq!(OperandSize::Byte.bits(), 8);
3980 assert_eq!(OperandSize::Word.bits(), 16);
3981 assert_eq!(OperandSize::Dword.bits(), 32);
3982 assert_eq!(OperandSize::Qword.bits(), 64);
3983 assert_eq!(OperandSize::Xmmword.bits(), 128);
3984 assert_eq!(OperandSize::Ymmword.bits(), 256);
3985 assert_eq!(OperandSize::Zmmword.bits(), 512);
3986 }
3987
3988 #[test]
3989 fn register_display() {
3990 assert_eq!(format!("{}", Register::Rax), "rax");
3991 assert_eq!(format!("{}", Register::R8d), "r8d");
3992 assert_eq!(format!("{}", Register::Xmm0), "xmm0");
3993 assert_eq!(format!("{}", Register::Ymm0), "ymm0");
3994 assert_eq!(format!("{}", Register::Zmm0), "zmm0");
3995 assert_eq!(format!("{}", Register::K0), "k0");
3996 }
3997
3998 #[test]
3999 fn operand_size_display() {
4000 assert_eq!(format!("{}", OperandSize::Byte), "byte");
4001 assert_eq!(format!("{}", OperandSize::Qword), "qword");
4002 }
4003
4004 #[test]
4005 fn data_size_display() {
4006 assert_eq!(format!("{}", DataSize::Byte), ".byte");
4007 assert_eq!(format!("{}", DataSize::Quad), ".quad");
4008 }
4009
4010 #[test]
4011 fn prefix_display() {
4012 assert_eq!(format!("{}", Prefix::Lock), "lock");
4013 assert_eq!(format!("{}", Prefix::Rep), "rep");
4014 }
4015
4016 #[test]
4017 fn operand_display() {
4018 assert_eq!(format!("{}", Operand::Register(Register::Rax)), "rax");
4019 assert_eq!(format!("{}", Operand::Immediate(42)), "0x2A");
4020 assert_eq!(format!("{}", Operand::Immediate(-1)), "-0x1");
4021 assert_eq!(format!("{}", Operand::Label(String::from("loop"))), "loop");
4022
4023 let mem = MemoryOperand {
4024 base: Some(Register::Rbp),
4025 disp: 8,
4026 ..Default::default()
4027 };
4028 assert_eq!(format!("{}", Operand::Memory(Box::new(mem))), "[rbp+0x8]");
4029
4030 let mem2 = MemoryOperand {
4031 base: Some(Register::Rbx),
4032 index: Some(Register::Rcx),
4033 scale: 4,
4034 disp: 0,
4035 size: Some(OperandSize::Dword),
4036 ..Default::default()
4037 };
4038 assert_eq!(
4039 format!("{}", Operand::Memory(Box::new(mem2))),
4040 "dword ptr [rbx+rcx*4]"
4041 );
4042 }
4043
4044 #[test]
4045 fn expr_display() {
4046 let expr = Expr::Add(
4047 Box::new(Expr::Label(String::from("foo"))),
4048 Box::new(Expr::Num(4)),
4049 );
4050 assert_eq!(format!("{}", expr), "(foo + 4)");
4051 }
4052
4053 #[test]
4054 fn expr_eval_numeric() {
4055 let e = Expr::Add(Box::new(Expr::Num(10)), Box::new(Expr::Num(20)));
4056 assert_eq!(e.eval(), Some(30));
4057 }
4058
4059 #[test]
4060 fn expr_eval_with_label_returns_none() {
4061 let e = Expr::Add(
4062 Box::new(Expr::Label(String::from("x"))),
4063 Box::new(Expr::Num(5)),
4064 );
4065 assert_eq!(e.eval(), None);
4066 }
4067
4068 #[test]
4069 fn expr_label_addend_add() {
4070 let e = Expr::Add(
4071 Box::new(Expr::Label(String::from("data"))),
4072 Box::new(Expr::Num(8)),
4073 );
4074 assert_eq!(e.label_addend(), Some(("data", 8)));
4075 }
4076
4077 #[test]
4078 fn expr_label_addend_sub() {
4079 let e = Expr::Sub(
4080 Box::new(Expr::Label(String::from("data"))),
4081 Box::new(Expr::Num(3)),
4082 );
4083 assert_eq!(e.label_addend(), Some(("data", -3)));
4084 }
4085
4086 #[test]
4087 fn expr_label_addend_plain_label() {
4088 let e = Expr::Label(String::from("foo"));
4089 assert_eq!(e.label_addend(), Some(("foo", 0)));
4090 }
4091
4092 #[test]
4093 fn expr_label_addend_two_labels_returns_none() {
4094 let e = Expr::Add(
4095 Box::new(Expr::Label(String::from("a"))),
4096 Box::new(Expr::Label(String::from("b"))),
4097 );
4098 assert_eq!(e.label_addend(), None);
4099 }
4100
4101 #[test]
4102 fn expr_resolve_constants() {
4103 let mut e = Expr::Add(
4104 Box::new(Expr::Label(String::from("SIZE"))),
4105 Box::new(Expr::Num(1)),
4106 );
4107 e.resolve_constants(|name| if name == "SIZE" { Some(10) } else { None });
4108 assert_eq!(e.eval(), Some(11));
4109 }
4110
4111 #[test]
4112 fn expr_resolve_constants_partial() {
4113 let mut e = Expr::Add(
4114 Box::new(Expr::Label(String::from("SIZE"))),
4115 Box::new(Expr::Label(String::from("unknown"))),
4116 );
4117 e.resolve_constants(|name| if name == "SIZE" { Some(10) } else { None });
4118 assert_eq!(e.eval(), None);
4120 }
4121}