6#if defined(TARGET_ARCH_ARM64)
15#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
17class ARM64Decoder :
public ValueObject {
21 buffer_[buffer_pos_] =
'\0';
28 void InstructionDecode(
uword pc);
32 void Print(
const char* str);
33 void PrintInt(
int value);
36 void PrintRegister(
int reg,
R31Type r31t);
37 void PrintVRegister(
int reg);
38 void PrintShiftExtendRm(Instr* instr);
39 void PrintMemOperand(Instr* instr);
40 void PrintPairMemOperand(Instr* instr);
41 void PrintS(Instr* instr);
42 void PrintCondition(Instr* instr);
43 void PrintInvertedCondition(Instr* instr);
46 int FormatRegister(Instr* instr,
const char* option);
47 int FormatVRegister(Instr* instr,
const char* option);
48 int FormatOption(Instr* instr,
const char*
format);
50 void Unknown(Instr* instr);
53#define DECODE_OP(op) void Decode##op(Instr* instr);
58 char* get_buffer()
const {
return buffer_; }
59 char* current_position_in_buffer() {
return buffer_ + buffer_pos_; }
60 size_t remaining_size_in_buffer() {
return buffer_size_ - buffer_pos_; }
71#define STRING_STARTS_WITH(string, compare_string) \
72 (strncmp(string, compare_string, strlen(compare_string)) == 0)
75void ARM64Decoder::Print(
const char* str) {
77 while (cur !=
'\0' && (buffer_pos_ < (buffer_size_ - 1))) {
78 buffer_[buffer_pos_++] = cur;
81 buffer_[buffer_pos_] =
'\0';
84void ARM64Decoder::PrintInt(
int value) {
86 remaining_size_in_buffer(),
"%d",
value);
87 buffer_[buffer_pos_] =
'\0';
91void ARM64Decoder::PrintRegister(
int reg,
R31Type r31t) {
95 const char* rstr = (r31t ==
R31IsZR) ?
"zr" :
"csp";
102void ARM64Decoder::PrintVRegister(
int reg) {
106 remaining_size_in_buffer(),
"v%d", reg);
111static const char* shift_names[
kMaxShift] = {
"lsl",
"lsr",
"asr",
"ror"};
113static const char* extend_names[
kMaxExtend] = {
114 "uxtb",
"uxth",
"uxtw",
"uxtx",
"sxtb",
"sxth",
"sxtw",
"sxtx",
120 "eq",
"ne",
"cs",
"cc",
"mi",
"pl",
"vs",
"vc",
121 "hi",
"ls",
"ge",
"lt",
"gt",
"le",
"",
"invalid",
125void ARM64Decoder::PrintCondition(Instr* instr) {
126 if (instr->IsConditionalSelectOp()) {
127 Print(cond_names[instr->SelectConditionField()]);
129 Print(cond_names[instr->ConditionField()]);
134void ARM64Decoder::PrintInvertedCondition(Instr* instr) {
135 if (instr->IsConditionalSelectOp()) {
144void ARM64Decoder::PrintShiftExtendRm(Instr* instr) {
145 int rm = instr->RmField();
146 Shift shift = instr->ShiftTypeField();
147 int shift_amount = instr->ShiftAmountField();
148 Extend extend = instr->ExtendTypeField();
149 int extend_shift_amount = instr->ExtShiftAmountField();
153 if (instr->IsShift() && (shift ==
LSL) && (shift_amount == 0)) {
157 if (instr->IsShift()) {
159 if ((shift ==
ROR) && (shift_amount == 0)) {
162 }
else if (((shift ==
LSR) || (shift ==
ASR)) && (shift_amount == 0)) {
166 Utils::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
167 " %s #%d", shift_names[shift], shift_amount);
169 ASSERT(instr->IsExtend());
172 Utils::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
173 " %s", extend_names[extend]);
174 if (((instr->SFField() == 1) && (extend ==
UXTX)) ||
175 ((instr->SFField() == 0) && (extend ==
UXTW))) {
178 remaining_size_in_buffer(),
" %d",
179 extend_shift_amount);
184void ARM64Decoder::PrintMemOperand(Instr* instr) {
185 const Register rn = instr->RnField();
186 if (instr->Bit(24) == 1) {
188 const uint32_t
scale = instr->SzField();
189 const uint32_t imm12 = instr->Imm12Field();
190 const uint32_t off = imm12 <<
scale;
195 remaining_size_in_buffer(),
", #%d", off);
199 switch (instr->Bits(10, 2)) {
202 const int32_t imm9 = instr->SImm9Field();
207 remaining_size_in_buffer(),
", #%d", imm9);
212 const int32_t imm9 = instr->SImm9Field();
219 remaining_size_in_buffer(),
", #%d !", imm9);
223 const Register rm = instr->RmField();
224 const Extend ext = instr->ExtendTypeField();
225 const int s = instr->Bit(12);
231 remaining_size_in_buffer(),
" %s",
240 const int32_t imm9 = instr->SImm9Field();
246 remaining_size_in_buffer(),
", #%d", imm9);
257void ARM64Decoder::PrintPairMemOperand(Instr* instr) {
258 const Register rn = instr->RnField();
259 const uint32_t simm7 = instr->SImm7Field();
260 const intptr_t shift =
261 (instr->Bit(26) == 1) ? 2 + instr->SzField() : 2 + instr->SFField();
262 const int32_t
offset = simm7 << shift;
265 switch (instr->Bits(23, 3)) {
270 remaining_size_in_buffer(),
"], #%d !",
offset);
276 remaining_size_in_buffer(),
", #%d]",
offset);
282 remaining_size_in_buffer(),
", #%d]!",
offset);
292int ARM64Decoder::FormatRegister(Instr* instr,
const char*
format) {
295 int reg = instr->RnField();
296 PrintRegister(reg, instr->RnMode());
298 }
else if (
format[1] ==
'd') {
299 int reg = instr->RdField();
300 PrintRegister(reg, instr->RdMode());
302 }
else if (
format[1] ==
'm') {
303 int reg = instr->RmField();
306 }
else if (
format[1] ==
't') {
308 int reg = instr->Rt2Field();
312 int reg = instr->RtField();
315 }
else if (
format[1] ==
'a') {
316 int reg = instr->RaField();
319 }
else if (
format[1] ==
's') {
320 int reg = instr->RsField();
328int ARM64Decoder::FormatVRegister(Instr* instr,
const char*
format) {
331 int reg = instr->VdField();
334 }
else if (
format[1] ==
'n') {
335 int reg = instr->VnField();
338 }
else if (
format[1] ==
'm') {
339 int reg = instr->VmField();
342 }
else if (
format[1] ==
't') {
344 int reg = instr->Vt2Field();
348 int reg = instr->VtField();
361int ARM64Decoder::FormatOption(Instr* instr,
const char*
format) {
366 const uint64_t imm = instr->ImmLogical();
369 remaining_size_in_buffer(),
"0x%" Px64, imm);
373 int bitpos = instr->Bits(19, 5) | (instr->Bit(31) << 5);
376 remaining_size_in_buffer(),
"#%d", bitpos);
383 const int32_t imm5 = instr->Bits(16, 5);
384 char const* typ =
"??";
385 if ((imm5 & 0x1) != 0) {
387 }
else if ((imm5 & 0x2) != 0) {
389 }
else if ((imm5 & 0x4) != 0) {
391 }
else if ((imm5 & 0x8) != 0) {
395 remaining_size_in_buffer(),
"%s", typ);
401 PrintInvertedCondition(instr);
404 PrintCondition(instr);
413 off =
static_cast<uint64_t
>(instr->SImm26Field()) << 2;
417 off =
static_cast<uint64_t
>(instr->SImm14Field()) << 2;
420 off =
static_cast<uint64_t
>(instr->SImm19Field()) << 2;
423 if (FLAG_disassemble_relative) {
426 remaining_size_in_buffer(),
"%+" Pd64 "", off);
428 uword destination =
reinterpret_cast<uword>(instr) + off;
431 remaining_size_in_buffer(),
"%#" Px "", destination);
437 const int sz = instr->SzField();
441 if (instr->Bit(23) == 1) {
461 remaining_size_in_buffer(),
"%s", sz_str);
466 const int shift = instr->HWField() << 4;
470 remaining_size_in_buffer(),
" lsl %d", shift);
478 const int32_t imm4 = instr->Bits(11, 4);
479 const int32_t imm5 = instr->Bits(16, 5);
484 }
else if (
format[3] ==
'5') {
489 if ((imm5 & 0x1) != 0) {
491 }
else if ((imm5 & 0x2) != 0) {
492 idx = imm >> (shift + 1);
493 }
else if ((imm5 & 0x4) != 0) {
494 idx = imm >> (shift + 2);
495 }
else if ((imm5 & 0x8) != 0) {
496 idx = imm >> (shift + 3);
499 remaining_size_in_buffer(),
"[%d]", idx);
501 }
else if (
format[3] ==
'1') {
506 imm = instr->Imm12Field();
509 if (instr->Imm12ShiftField() == 1) {
511 }
else if ((instr->Imm12ShiftField() & 0x2) != 0) {
512 Print(
"Unknown Shift");
518 imm = instr->Imm16Field();
522 remaining_size_in_buffer(),
"#0x%" Px64, imm);
527 double dimm = bit_cast<double, int64_t>(
530 remaining_size_in_buffer(),
"%f", dimm);
532 }
else if (
format[3] ==
'r') {
533 int immr = instr->ImmRField();
536 remaining_size_in_buffer(),
"#%d", immr);
540 int imms = instr->ImmSField();
543 remaining_size_in_buffer(),
"#%d", imms);
550 PrintMemOperand(instr);
555 if (instr->Bit(26) == 0) {
556 if (instr->Bit(31) == 0) {
557 if (instr->Bit(30) == 1) {
566 switch (instr->Bits(30, 2)) {
588 const uint64_t immhi = instr->SImm19Field();
589 const uint64_t immlo = instr->Bits(29, 2);
590 off = (immhi << 2) | immlo;
593 off = instr->SImm19Field() << 2;
595 if (FLAG_disassemble_relative) {
598 remaining_size_in_buffer(),
"%+" Pd64 "", off);
600 const uint64_t pc =
reinterpret_cast<int64_t
>(instr);
601 const uint64_t
dest = pc + off;
604 remaining_size_in_buffer(),
"0x%" Px64,
dest);
609 PrintPairMemOperand(instr);
614 return FormatRegister(instr,
format);
619 char const* sz_str =
nullptr;
620 if (instr->Bits(14, 2) == 3) {
621 switch (instr->Bit(22)) {
633 switch (instr->Bit(22)) {
646 remaining_size_in_buffer(),
"%s", sz_str);
649 return FormatVRegister(instr,
format);
655 PrintShiftExtendRm(instr);
657 }
else if (
format[1] ==
'f') {
659 if (instr->SFField() == 1) {
665 }
else if (
format[1] ==
'z') {
667 const int sz = instr->SzField();
688 remaining_size_in_buffer(),
"%s", sz_str);
690 }
else if (
format[1] ==
' ') {
713 while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) {
717 buffer_[buffer_pos_++] = cur;
721 buffer_[buffer_pos_] =
'\0';
726void ARM64Decoder::Unknown(Instr* instr) {
730void ARM64Decoder::DecodeMoveWide(Instr* instr) {
731 switch (instr->Bits(29, 2)) {
733 Format(instr,
"movn'sf 'rd, 'imm16'hw");
736 Format(instr,
"movz'sf 'rd, 'imm16'hw");
739 Format(instr,
"movk'sf 'rd, 'imm16'hw");
747void ARM64Decoder::DecodeLoadStoreReg(Instr* instr) {
748 if (instr->Bit(26) == 1) {
750 if (instr->Bit(22) == 1) {
751 Format(instr,
"fldr'fsz 'vt, 'memop");
753 Format(instr,
"fstr'fsz 'vt, 'memop");
757 if (instr->Bits(22, 2) == 0) {
758 Format(instr,
"str'sz 'rt, 'memop");
759 }
else if (instr->Bits(23, 1) == 1) {
760 Format(instr,
"ldrs'sz 'rt, 'memop");
762 Format(instr,
"ldr'sz 'rt, 'memop");
767void ARM64Decoder::DecodeLoadStoreRegPair(Instr* instr) {
768 if (instr->Bit(26) == 1) {
770 if (instr->Bit(22) == 1) {
771 Format(instr,
"fldp'opc 'vt, 'vt2, 'pmemop");
773 Format(instr,
"fstp'opc 'vt, 'vt2, 'pmemop");
777 if (instr->Bit(22) == 1) {
778 Format(instr,
"ldp'opc 'rt, 'rt2, 'pmemop");
780 Format(instr,
"stp'opc 'rt, 'rt2, 'pmemop");
785void ARM64Decoder::DecodeLoadRegLiteral(Instr* instr) {
786 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) ||
787 (instr->Bits(24, 3) != 0)) {
790 if (instr->Bit(30) != 0) {
791 Format(instr,
"ldrx 'rt, 'pcldr");
793 Format(instr,
"ldrw 'rt, 'pcldr");
797void ARM64Decoder::DecodeLoadStoreExclusive(Instr* instr) {
798 if (instr->Bit(32) != 1 || instr->Bit(21) != 0 ||
799 instr->Bit(23) != instr->Bit(15)) {
803 const bool is_load = instr->Bit(22) == 1;
804 const bool is_exclusive = instr->Bit(23) == 0;
805 const bool is_ordered = instr->Bit(15) == 1;
807 const bool is_load_acquire = !is_exclusive && is_ordered;
808 if (is_load_acquire) {
809 Format(instr,
"ldar'sz 'rt, ['rn]");
811 Format(instr,
"ldxr'sz 'rt, ['rn]");
814 const bool is_store_release = !is_exclusive && is_ordered;
815 if (is_store_release) {
816 Format(instr,
"stlr'sz 'rt, ['rn]");
818 Format(instr,
"stxr'sz 'rs, 'rt, ['rn]");
823void ARM64Decoder::DecodeAtomicMemory(Instr* instr) {
824 switch (instr->Bits(12, 3)) {
826 Format(instr,
"ldclr'sz 'rs, 'rt, ['rn]");
829 Format(instr,
"ldset'sz 'rs, 'rt, ['rn]");
837void ARM64Decoder::DecodeAddSubImm(Instr* instr) {
838 switch (instr->Bit(30)) {
840 if ((instr->RdField() ==
R31) && (instr->SField() == 1)) {
841 Format(instr,
"cmn'sf 'rn, 'imm12s");
843 if (((instr->RdField() ==
R31) || (instr->RnField() ==
R31)) &&
844 (instr->Imm12Field() == 0) && (instr->Bit(29) == 0)) {
845 Format(instr,
"mov'sf 'rd, 'rn");
847 Format(instr,
"add'sf's 'rd, 'rn, 'imm12s");
853 if ((instr->RdField() ==
R31) && (instr->SField() == 1)) {
854 Format(instr,
"cmp'sf 'rn, 'imm12s");
856 Format(instr,
"sub'sf's 'rd, 'rn, 'imm12s");
866void ARM64Decoder::DecodeBitfield(Instr* instr) {
867 int reg_size = instr->SFField() == 0 ? 32 : 64;
868 int op = instr->Bits(29, 2);
869 int r_imm = instr->ImmRField();
870 int s_imm = instr->ImmSField();
875 Format(instr,
"sxtb 'rd, 'rn");
877 }
else if (s_imm == 15) {
878 Format(instr,
"sxth 'rd, 'rn");
880 }
else if (s_imm == 31) {
881 Format(instr,
"sxtw 'rd, 'rn");
885 if (s_imm == (reg_size - 1)) {
886 Format(instr,
"asr'sf 'rd, 'rn, 'immr");
889 Format(instr,
"sbfm'sf 'rd, 'rn, 'immr, 'imms");
892 Format(instr,
"bfm'sf 'rd, 'rn, 'immr, 'imms");
897 Format(instr,
"uxtb 'rd, 'rn");
899 }
else if (s_imm == 15) {
900 Format(instr,
"uxth 'rd, 'rn");
904 if ((s_imm != (reg_size - 1)) && ((s_imm + 1) == r_imm)) {
905 int shift = reg_size - s_imm - 1;
906 Format(instr,
"lsl'sf 'rd, 'rn, #");
909 }
else if (s_imm == (reg_size - 1)) {
910 Format(instr,
"lsr'sf 'rd, 'rn, 'immr");
913 Format(instr,
"ubfm'sf 'rd, 'rn, 'immr, 'imms");
921void ARM64Decoder::DecodeLogicalImm(Instr* instr) {
922 int op = instr->Bits(29, 2);
925 Format(instr,
"and'sf 'rd, 'rn, 'bitimm");
928 if (instr->RnField() ==
R31) {
929 Format(instr,
"mov'sf 'rd, 'bitimm");
931 Format(instr,
"orr'sf 'rd, 'rn, 'bitimm");
936 Format(instr,
"eor'sf 'rd, 'rn, 'bitimm");
939 if (instr->RdField() ==
R31) {
940 Format(instr,
"tst'sf 'rn, 'bitimm");
942 Format(instr,
"and'sfs 'rd, 'rn, 'bitimm");
951void ARM64Decoder::DecodePCRel(Instr* instr) {
952 const int op = instr->Bit(31);
954 Format(instr,
"adr 'rd, 'pcadr");
960void ARM64Decoder::DecodeDPImmediate(Instr* instr) {
961 if (instr->IsMoveWideOp()) {
962 DecodeMoveWide(instr);
963 }
else if (instr->IsAddSubImmOp()) {
964 DecodeAddSubImm(instr);
965 }
else if (instr->IsBitfieldOp()) {
966 DecodeBitfield(instr);
967 }
else if (instr->IsLogicalImmOp()) {
968 DecodeLogicalImm(instr);
969 }
else if (instr->IsPCRelOp()) {
976void ARM64Decoder::DecodeExceptionGen(Instr* instr) {
977 if ((instr->Bits(0, 2) == 1) && (instr->Bits(2, 3) == 0) &&
978 (instr->Bits(21, 3) == 0)) {
979 Format(instr,
"svc 'imm16");
980 }
else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) &&
981 (instr->Bits(21, 3) == 1)) {
982 Format(instr,
"brk 'imm16");
983 }
else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) &&
984 (instr->Bits(21, 3) == 2)) {
985 Format(instr,
"hlt 'imm16");
991void ARM64Decoder::DecodeSystem(Instr* instr) {
992 if (instr->InstructionBits() ==
CLREX) {
997 if ((instr->Bits(0, 8) == 0x1f) && (instr->Bits(12, 4) == 2) &&
998 (instr->Bits(16, 3) == 3) && (instr->Bits(19, 2) == 0) &&
999 (instr->Bit(21) == 0)) {
1000 if (instr->Bits(8, 4) == 0) {
1010void ARM64Decoder::DecodeUnconditionalBranchReg(Instr* instr) {
1011 if ((instr->Bits(0, 5) == 0) && (instr->Bits(10, 5) == 0) &&
1012 (instr->Bits(16, 5) == 0x1f)) {
1013 switch (instr->Bits(21, 4)) {
1018 Format(instr,
"blr 'rn");
1024 Format(instr,
"ret 'rn");
1034void ARM64Decoder::DecodeCompareAndBranch(Instr* instr) {
1035 const int op = instr->Bit(24);
1037 Format(instr,
"cbz'sf 'rt, 'dest19");
1039 Format(instr,
"cbnz'sf 'rt, 'dest19");
1043void ARM64Decoder::DecodeConditionalBranch(Instr* instr) {
1044 if ((instr->Bit(24) != 0) || (instr->Bit(4) != 0)) {
1048 Format(instr,
"b'cond 'dest19");
1051void ARM64Decoder::DecodeTestAndBranch(Instr* instr) {
1052 const int op = instr->Bit(24);
1054 Format(instr,
"tbz'sf 'rt, 'bitpos, 'dest14");
1056 Format(instr,
"tbnz'sf 'rt, 'bitpos, 'dest14");
1060void ARM64Decoder::DecodeUnconditionalBranch(Instr* instr) {
1061 const int op = instr->Bit(31);
1063 Format(instr,
"b 'dest26");
1065 Format(instr,
"bl 'dest26");
1069void ARM64Decoder::DecodeCompareBranch(Instr* instr) {
1070 if (instr->IsExceptionGenOp()) {
1071 DecodeExceptionGen(instr);
1072 }
else if (instr->IsSystemOp()) {
1073 DecodeSystem(instr);
1074 }
else if (instr->IsUnconditionalBranchRegOp()) {
1075 DecodeUnconditionalBranchReg(instr);
1076 }
else if (instr->IsCompareAndBranchOp()) {
1077 DecodeCompareAndBranch(instr);
1078 }
else if (instr->IsConditionalBranchOp()) {
1079 DecodeConditionalBranch(instr);
1080 }
else if (instr->IsTestAndBranchOp()) {
1081 DecodeTestAndBranch(instr);
1082 }
else if (instr->IsUnconditionalBranchOp()) {
1083 DecodeUnconditionalBranch(instr);
1089void ARM64Decoder::DecodeLoadStore(Instr* instr) {
1090 if (instr->IsAtomicMemoryOp()) {
1091 DecodeAtomicMemory(instr);
1092 }
else if (instr->IsLoadStoreRegOp()) {
1093 DecodeLoadStoreReg(instr);
1094 }
else if (instr->IsLoadStoreRegPairOp()) {
1095 DecodeLoadStoreRegPair(instr);
1096 }
else if (instr->IsLoadRegLiteralOp()) {
1097 DecodeLoadRegLiteral(instr);
1098 }
else if (instr->IsLoadStoreExclusiveOp()) {
1099 DecodeLoadStoreExclusive(instr);
1105void ARM64Decoder::DecodeAddSubShiftExt(Instr* instr) {
1106 switch (instr->Bit(30)) {
1108 if (instr->RdField() ==
R31) {
1109 Format(instr,
"cmn'sf 'rn, 'shift_op");
1111 Format(instr,
"add'sf's 'rd, 'rn, 'shift_op");
1116 if (instr->RdField() ==
R31) {
1117 Format(instr,
"cmp'sf 'rn, 'shift_op");
1119 if (instr->RnField() ==
R31) {
1120 Format(instr,
"neg'sf's 'rd, 'shift_op");
1122 Format(instr,
"sub'sf's 'rd, 'rn, 'shift_op");
1133void ARM64Decoder::DecodeAddSubWithCarry(Instr* instr) {
1134 switch (instr->Bit(30)) {
1136 Format(instr,
"adc'sf's 'rd, 'rn, 'rm");
1140 Format(instr,
"sbc'sf's 'rd, 'rn, 'rm");
1149void ARM64Decoder::DecodeLogicalShift(Instr* instr) {
1150 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21);
1153 Format(instr,
"and'sf 'rd, 'rn, 'shift_op");
1156 Format(instr,
"bic'sf 'rd, 'rn, 'shift_op");
1159 if ((instr->RnField() ==
R31) && (instr->IsShift()) &&
1160 (instr->ShiftTypeField() ==
LSL)) {
1161 if (instr->ShiftAmountField() == 0) {
1162 Format(instr,
"mov'sf 'rd, 'rm");
1164 Format(instr,
"lsl'sf 'rd, 'rm, 'imms");
1167 Format(instr,
"orr'sf 'rd, 'rn, 'shift_op");
1172 Format(instr,
"orn'sf 'rd, 'rn, 'shift_op");
1175 Format(instr,
"eor'sf 'rd, 'rn, 'shift_op");
1178 Format(instr,
"eon'sf 'rd, 'rn, 'shift_op");
1181 if (instr->RdField() ==
R31) {
1182 Format(instr,
"tst'sf 'rn, 'shift_op");
1184 Format(instr,
"and'sfs 'rd, 'rn, 'shift_op");
1188 Format(instr,
"bic'sfs 'rd, 'rn, 'shift_op");
1196void ARM64Decoder::DecodeMiscDP1Source(Instr* instr) {
1197 if (instr->Bit(29) != 0) {
1201 const int op = instr->Bits(10, 10);
1204 Format(instr,
"rbit'sf 'rd, 'rn");
1207 Format(instr,
"clz'sf 'rd, 'rn");
1215void ARM64Decoder::DecodeMiscDP2Source(Instr* instr) {
1216 if (instr->Bit(29) != 0) {
1220 const int op = instr->Bits(10, 5);
1223 Format(instr,
"udiv'sf 'rd, 'rn, 'rm");
1226 Format(instr,
"sdiv'sf 'rd, 'rn, 'rm");
1229 Format(instr,
"lsl'sf 'rd, 'rn, 'rm");
1232 Format(instr,
"lsr'sf 'rd, 'rn, 'rm");
1235 Format(instr,
"asr'sf 'rd, 'rn, 'rm");
1243void ARM64Decoder::DecodeMiscDP3Source(Instr* instr) {
1244 bool zero_operand = instr->RaField() ==
R31;
1246 int32_t
bits = instr->InstructionBits() & mask;
1250 Format(instr,
"mul'sf 'rd, 'rn, 'rm");
1252 Format(instr,
"madd'sf 'rd, 'rn, 'rm, 'ra");
1256 Format(instr,
"mneg'sf 'rd, 'rn, 'rm");
1258 Format(instr,
"msub'sf 'rd, 'rn, 'rm, 'ra");
1261 Format(instr,
"smulh 'rd, 'rn, 'rm");
1263 Format(instr,
"umulh 'rd, 'rn, 'rm");
1266 Format(instr,
"umull 'rd, 'rn, 'rm");
1268 Format(instr,
"umaddl 'rd, 'rn, 'rm, 'ra");
1272 Format(instr,
"smull 'rd, 'rn, 'rm");
1274 Format(instr,
"smaddl 'rd, 'rn, 'rm, 'ra");
1278 Format(instr,
"smnegl 'rd, 'rn, 'rm");
1280 Format(instr,
"smsubl 'rd, 'rn, 'rm, 'ra");
1284 Format(instr,
"umnegl 'rd, 'rn, 'rm");
1286 Format(instr,
"umsubl 'rd, 'rn, 'rm, 'ra");
1293void ARM64Decoder::DecodeConditionalSelect(Instr* instr) {
1294 int cond = instr->SelectConditionField();
1296 (instr->RnField() == instr->RmField()) && ((cond & 0xe) != 0xe);
1297 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) {
1298 Format(instr,
"csel'sf 'rd, 'rn, 'rm, 'cond");
1299 }
else if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 1)) {
1301 Format(instr,
"csinc'sf 'rd, 'rn, 'rm, 'cond");
1303 Format(instr,
"cinc'sf 'rd, 'rn, 'condinverted");
1305 }
else if ((instr->Bits(29, 2) == 2) && (instr->Bits(10, 2) == 0)) {
1307 Format(instr,
"cinv'sf 'rd, 'rn, 'condinverted");
1309 Format(instr,
"csinv'sf 'rd, 'rn, 'rm, 'cond");
1311 }
else if ((instr->Bits(29, 2) == 2) && (instr->Bits(10, 2) == 1)) {
1313 Format(instr,
"cneg'sf 'rd, 'rn, 'condinverted");
1315 Format(instr,
"csneg'sf 'rd, 'rn, 'rm, 'cond");
1322void ARM64Decoder::DecodeDPRegister(Instr* instr) {
1323 if (instr->IsAddSubShiftExtOp()) {
1324 DecodeAddSubShiftExt(instr);
1325 }
else if (instr->IsAddSubWithCarryOp()) {
1326 DecodeAddSubWithCarry(instr);
1327 }
else if (instr->IsLogicalShiftOp()) {
1328 DecodeLogicalShift(instr);
1329 }
else if (instr->IsMiscDP1SourceOp()) {
1330 DecodeMiscDP1Source(instr);
1331 }
else if (instr->IsMiscDP2SourceOp()) {
1332 DecodeMiscDP2Source(instr);
1333 }
else if (instr->IsMiscDP3SourceOp()) {
1334 DecodeMiscDP3Source(instr);
1335 }
else if (instr->IsConditionalSelectOp()) {
1336 DecodeConditionalSelect(instr);
1342void ARM64Decoder::DecodeSIMDCopy(Instr* instr) {
1343 const int32_t
Q = instr->Bit(30);
1344 const int32_t op = instr->Bit(29);
1345 const int32_t imm4 = instr->Bits(11, 4);
1347 if ((op == 0) && (imm4 == 7)) {
1349 Format(instr,
"vmovrs 'rd, 'vn'idx5");
1351 Format(instr,
"vmovrd 'rd, 'vn'idx5");
1353 }
else if ((
Q == 1) && (op == 0) && (imm4 == 0)) {
1354 Format(instr,
"vdup'csz 'vd, 'vn'idx5");
1355 }
else if ((
Q == 1) && (op == 0) && (imm4 == 3)) {
1356 Format(instr,
"vins'csz 'vd'idx5, 'rn");
1357 }
else if ((
Q == 1) && (op == 0) && (imm4 == 1)) {
1358 Format(instr,
"vdup'csz 'vd, 'rn");
1359 }
else if ((
Q == 1) && (op == 1)) {
1360 Format(instr,
"vins'csz 'vd'idx5, 'vn'idx4");
1366void ARM64Decoder::DecodeSIMDThreeSame(Instr* instr) {
1367 const int32_t
Q = instr->Bit(30);
1368 const int32_t
U = instr->Bit(29);
1369 const int32_t opcode = instr->Bits(11, 5);
1376 if ((
U == 0) && (opcode == 0x3)) {
1377 if (instr->Bit(23) == 0) {
1378 Format(instr,
"vand 'vd, 'vn, 'vm");
1380 Format(instr,
"vorr 'vd, 'vn, 'vm");
1382 }
else if ((
U == 1) && (opcode == 0x3)) {
1383 Format(instr,
"veor 'vd, 'vn, 'vm");
1384 }
else if ((
U == 0) && (opcode == 0x10)) {
1385 Format(instr,
"vadd'vsz 'vd, 'vn, 'vm");
1386 }
else if ((
U == 1) && (opcode == 0x10)) {
1387 Format(instr,
"vsub'vsz 'vd, 'vn, 'vm");
1388 }
else if ((
U == 0) && (opcode == 0x1a)) {
1389 if (instr->Bit(23) == 0) {
1390 Format(instr,
"vadd'vsz 'vd, 'vn, 'vm");
1392 Format(instr,
"vsub'vsz 'vd, 'vn, 'vm");
1394 }
else if ((
U == 1) && (opcode == 0x1b)) {
1395 Format(instr,
"vmul'vsz 'vd, 'vn, 'vm");
1396 }
else if ((
U == 1) && (opcode == 0x1f)) {
1397 Format(instr,
"vdiv'vsz 'vd, 'vn, 'vm");
1398 }
else if ((
U == 0) && (opcode == 0x1c)) {
1399 Format(instr,
"vceq'vsz 'vd, 'vn, 'vm");
1400 }
else if ((
U == 1) && (opcode == 0x1c)) {
1401 if (instr->Bit(23) == 1) {
1402 Format(instr,
"vcgt'vsz 'vd, 'vn, 'vm");
1404 Format(instr,
"vcge'vsz 'vd, 'vn, 'vm");
1406 }
else if ((
U == 0) && (opcode == 0x1e)) {
1407 if (instr->Bit(23) == 1) {
1408 Format(instr,
"vmin'vsz 'vd, 'vn, 'vm");
1410 Format(instr,
"vmax'vsz 'vd, 'vn, 'vm");
1412 }
else if ((
U == 0) && (opcode == 0x1f)) {
1413 if (instr->Bit(23) == 1) {
1414 Format(instr,
"vrsqrt'vsz 'vd, 'vn, 'vm");
1416 Format(instr,
"vrecps'vsz 'vd, 'vn, 'vm");
1423void ARM64Decoder::DecodeSIMDTwoReg(Instr* instr) {
1424 const int32_t
Q = instr->Bit(30);
1425 const int32_t
U = instr->Bit(29);
1426 const int32_t op = instr->Bits(12, 5);
1427 const int32_t sz = instr->Bits(22, 2);
1434 if ((
U == 1) && (op == 0x5)) {
1435 Format(instr,
"vnot 'vd, 'vn");
1436 }
else if ((
U == 0) && (op == 0xf)) {
1438 Format(instr,
"vabss 'vd, 'vn");
1439 }
else if (sz == 3) {
1440 Format(instr,
"vabsd 'vd, 'vn");
1444 }
else if ((
U == 1) && (op == 0xf)) {
1446 Format(instr,
"vnegs 'vd, 'vn");
1447 }
else if (sz == 3) {
1448 Format(instr,
"vnegd 'vd, 'vn");
1452 }
else if ((
U == 1) && (op == 0x1f)) {
1454 Format(instr,
"vsqrts 'vd, 'vn");
1455 }
else if (sz == 3) {
1456 Format(instr,
"vsqrtd 'vd, 'vn");
1460 }
else if ((
U == 0) && (op == 0x1d)) {
1465 Format(instr,
"vrecpes 'vd, 'vn");
1466 }
else if ((
U == 1) && (op == 0x1d)) {
1471 Format(instr,
"vrsqrtes 'vd, 'vn");
1477void ARM64Decoder::DecodeDPSimd1(Instr* instr) {
1478 if (instr->IsSIMDCopyOp()) {
1479 DecodeSIMDCopy(instr);
1480 }
else if (instr->IsSIMDThreeSameOp()) {
1481 DecodeSIMDThreeSame(instr);
1482 }
else if (instr->IsSIMDTwoRegOp()) {
1483 DecodeSIMDTwoReg(instr);
1489void ARM64Decoder::DecodeFPImm(Instr* instr) {
1490 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) ||
1491 (instr->Bits(5, 5) != 0)) {
1495 if (instr->Bit(22) == 1) {
1497 Format(instr,
"fmovd 'vd, 'immd");
1504void ARM64Decoder::DecodeFPIntCvt(Instr* instr) {
1505 if ((instr->Bit(29) != 0)) {
1510 if ((instr->SFField() == 0) && (instr->Bits(22, 2) == 0)) {
1511 if (instr->Bits(16, 5) == 6) {
1512 Format(instr,
"fmovrs'sf 'rd, 'vn");
1513 }
else if (instr->Bits(16, 5) == 7) {
1514 Format(instr,
"fmovsr'sf 'vd, 'rn");
1518 }
else if (instr->Bits(22, 2) == 1) {
1519 if (instr->Bits(16, 5) == 2) {
1520 Format(instr,
"scvtfd'sf 'vd, 'rn");
1521 }
else if (instr->Bits(16, 5) == 6) {
1522 Format(instr,
"fmovrd'sf 'rd, 'vn");
1523 }
else if (instr->Bits(16, 5) == 7) {
1524 Format(instr,
"fmovdr'sf 'vd, 'rn");
1525 }
else if (instr->Bits(16, 5) == 8) {
1526 Format(instr,
"fcvtps'sf 'rd, 'vn");
1527 }
else if (instr->Bits(16, 5) == 16) {
1528 Format(instr,
"fcvtms'sf 'rd, 'vn");
1529 }
else if (instr->Bits(16, 5) == 24) {
1530 Format(instr,
"fcvtzs'sf 'rd, 'vn");
1539void ARM64Decoder::DecodeFPOneSource(Instr* instr) {
1540 const int opc = instr->Bits(15, 6);
1542 if ((opc != 5) && (instr->Bit(22) != 1)) {
1551 Format(instr,
"fmovdd 'vd, 'vn");
1554 Format(instr,
"fabsd 'vd, 'vn");
1557 Format(instr,
"fnegd 'vd, 'vn");
1560 Format(instr,
"fsqrtd 'vd, 'vn");
1563 Format(instr,
"fcvtsd 'vd, 'vn");
1566 Format(instr,
"fcvtds 'vd, 'vn");
1574void ARM64Decoder::DecodeFPTwoSource(Instr* instr) {
1575 if (instr->Bits(22, 2) != 1) {
1579 const int opc = instr->Bits(12, 4);
1583 Format(instr,
"fmuld 'vd, 'vn, 'vm");
1586 Format(instr,
"fdivd 'vd, 'vn, 'vm");
1589 Format(instr,
"faddd 'vd, 'vn, 'vm");
1592 Format(instr,
"fsubd 'vd, 'vn, 'vm");
1600void ARM64Decoder::DecodeFPCompare(Instr* instr) {
1601 if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) {
1602 Format(instr,
"fcmpd 'vn, 'vm");
1603 }
else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) {
1604 if (instr->VmField() ==
V0) {
1605 Format(instr,
"fcmpd 'vn, #0.0");
1614void ARM64Decoder::DecodeFP(Instr* instr) {
1615 if (instr->IsFPImmOp()) {
1617 }
else if (instr->IsFPIntCvtOp()) {
1618 DecodeFPIntCvt(instr);
1619 }
else if (instr->IsFPOneSourceOp()) {
1620 DecodeFPOneSource(instr);
1621 }
else if (instr->IsFPTwoSourceOp()) {
1622 DecodeFPTwoSource(instr);
1623 }
else if (instr->IsFPCompareOp()) {
1624 DecodeFPCompare(instr);
1630void ARM64Decoder::DecodeDPSimd2(Instr* instr) {
1631 if (instr->IsFPOp()) {
1638void ARM64Decoder::InstructionDecode(
uword pc) {
1641 if (instr->IsDPImmediateOp()) {
1642 DecodeDPImmediate(instr);
1643 }
else if (instr->IsCompareBranchOp()) {
1644 DecodeCompareBranch(instr);
1645 }
else if (instr->IsLoadStoreOp()) {
1646 DecodeLoadStore(instr);
1647 }
else if (instr->IsDPRegisterOp()) {
1648 DecodeDPRegister(instr);
1649 }
else if (instr->IsDPSimd1Op()) {
1650 DecodeDPSimd1(instr);
1651 }
else if (instr->IsDPSimd2Op()) {
1652 DecodeDPSimd2(instr);
1661 intptr_t human_size,
1662 int* out_instr_size,
1666 ARM64Decoder decoder(human_buffer, human_size);
1667 decoder.InstructionDecode(pc);
1670 if (out_instr_size !=
nullptr) {
1675 if (!
code.IsNull()) {
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
static void DecodeInstruction(char *hex_buffer, intptr_t hex_size, char *human_buffer, intptr_t human_size, int *out_instr_len, const Code &code, Object **object, uword pc)
static Instr * At(uword pc)
int32_t InstructionBits() const
static int64_t VFPExpandImm(uint8_t imm8)
static int SNPrint(char *str, size_t size, const char *format,...) PRINTF_ATTRIBUTE(3
#define APPLY_OP_LIST(_V)
uint32_t uint32_t * format
static Condition InvertCondition(Condition c)
bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code &code, Object *obj)
const char *const cpu_reg_names[kNumberOfCpuRegisters]
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
def Format(template, **parameters)