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] ==
' ') {
711void ARM64Decoder::Format(Instr* instr,
const char*
format) {
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");
1254 }
else if (bits ==
MSUB || bits ==
MSUBW) {
1256 Format(instr,
"mneg'sf 'rd, 'rn, 'rm");
1258 Format(instr,
"msub'sf 'rd, 'rn, 'rm, 'ra");
1260 }
else if (bits ==
SMULH) {
1261 Format(instr,
"smulh 'rd, 'rn, 'rm");
1262 }
else if (bits ==
UMULH) {
1263 Format(instr,
"umulh 'rd, 'rn, 'rm");
1264 }
else if (bits ==
UMADDL) {
1266 Format(instr,
"umull 'rd, 'rn, 'rm");
1268 Format(instr,
"umaddl 'rd, 'rn, 'rm, 'ra");
1270 }
else if (bits ==
SMADDL) {
1272 Format(instr,
"smull 'rd, 'rn, 'rm");
1274 Format(instr,
"smaddl 'rd, 'rn, 'rm, 'ra");
1276 }
else if (bits ==
SMSUBL) {
1278 Format(instr,
"smnegl 'rd, 'rn, 'rm");
1280 Format(instr,
"smsubl 'rd, 'rn, 'rm, 'ra");
1282 }
else if (bits ==
UMSUBL) {
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)
static const uint8_t buffer[]
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]
Format(template, **parameters)