6#if defined(TARGET_ARCH_ARM)
16#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
18class ARMDecoder :
public ValueObject {
22 buffer_[buffer_pos_] =
'\0';
29 void InstructionDecode(uword pc);
33 void Print(
const char* str);
36 void PrintRegister(
int reg);
37 void PrintSRegister(
int reg);
38 void PrintDRegister(
int reg);
39 void PrintDRegisterList(
int start,
int reg_count);
40 void PrintQRegister(
int reg);
41 void PrintCondition(Instr* instr);
42 void PrintShiftRm(Instr* instr);
43 void PrintShiftImm(Instr* instr);
44 void PrintPU(Instr* instr);
47 int FormatRegister(Instr* instr,
const char* option);
48 int FormatSRegister(Instr* instr,
const char* option);
49 int FormatDRegister(Instr* instr,
const char* option);
50 int FormatQRegister(Instr* instr,
const char* option);
51 int FormatOption(Instr* instr,
const char* option);
53 void Unknown(Instr* instr);
59 void DecodeType01(Instr* instr);
60 void DecodeType2(Instr* instr);
61 void DecodeType3(Instr* instr);
62 void DecodeType4(Instr* instr);
63 void DecodeType5(Instr* instr);
64 void DecodeType6(Instr* instr);
65 void DecodeType7(Instr* instr);
66 void DecodeSIMDDataProcessing(Instr* instr);
69 char* get_buffer()
const {
return buffer_; }
70 char* current_position_in_buffer() {
return buffer_ + buffer_pos_; }
71 size_t remaining_size_in_buffer() {
return buffer_size_ - buffer_pos_; }
82#define STRING_STARTS_WITH(string, compare_string) \
83 (strncmp(string, compare_string, strlen(compare_string)) == 0)
86void ARMDecoder::Print(
const char* str) {
88 while (cur !=
'\0' && (buffer_pos_ < (buffer_size_ - 1))) {
89 buffer_[buffer_pos_++] = cur;
92 buffer_[buffer_pos_] =
'\0';
98 "eq",
"ne",
"cs",
"cc",
"mi",
"pl",
"vs",
"vc",
99 "hi",
"ls",
"ge",
"lt",
"gt",
"le",
"",
"invalid",
103void ARMDecoder::PrintCondition(Instr* instr) {
104 Print(cond_names[instr->ConditionField()]);
108void ARMDecoder::PrintRegister(
int reg) {
114void ARMDecoder::PrintSRegister(
int reg) {
118 remaining_size_in_buffer(),
"s%d", reg);
121void ARMDecoder::PrintDRegister(
int reg) {
125 remaining_size_in_buffer(),
"d%d", reg);
128void ARMDecoder::PrintQRegister(
int reg) {
132 remaining_size_in_buffer(),
"q%d", reg);
137static const char* shift_names[
kMaxShift] = {
"lsl",
"lsr",
"asr",
"ror"};
141void ARMDecoder::PrintShiftRm(Instr* instr) {
142 Shift shift = instr->ShiftField();
143 int shift_amount = instr->ShiftAmountField();
144 int rm = instr->RmField();
148 if ((instr->RegShiftField() == 0) && (shift ==
LSL) && (shift_amount == 0)) {
152 if (instr->RegShiftField() == 0) {
154 if ((shift ==
ROR) && (shift_amount == 0)) {
157 }
else if (((shift ==
LSR) || (shift ==
ASR)) && (shift_amount == 0)) {
161 Utils::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
162 ", %s #%d", shift_names[shift], shift_amount);
165 int rs = instr->RsField();
167 Utils::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
168 ", %s ", shift_names[shift]);
175void ARMDecoder::PrintShiftImm(Instr* instr) {
176 uint8_t
rotate = instr->RotateField() * 2;
177 int32_t immed8 = instr->Immed8Field();
180 remaining_size_in_buffer(),
"#%d", imm);
184void ARMDecoder::PrintPU(Instr* instr) {
185 switch (instr->PUField()) {
211int ARMDecoder::FormatRegister(Instr* instr,
const char*
format) {
214 int reg = instr->RnField();
217 }
else if (
format[1] ==
'd') {
218 int reg = instr->RdField();
221 if (instr->HasSign() && !instr->HasL()) {
222 if ((reg % 2) != 0) {
223 Print(
" *** unknown (odd register pair) ***");
226 PrintRegister(reg + 1);
232 }
else if (
format[1] ==
's') {
233 int reg = instr->RsField();
236 }
else if (
format[1] ==
'm') {
237 int reg = instr->RmField();
240 }
else if (
format[1] ==
'l') {
243 int rlist = instr->RlistField();
248 if ((rlist & 1) != 0) {
250 if ((rlist >> 1) != 0) {
264int ARMDecoder::FormatSRegister(Instr* instr,
const char*
format) {
267 int reg = instr->SnField();
270 }
else if (
format[1] ==
'd') {
271 int reg = instr->SdField();
274 }
else if (
format[1] ==
'm') {
275 int reg = instr->SmField();
285 }
else if (
format[1] ==
'l') {
287 int reg_count = instr->Bits(0, 8);
288 int start = instr->Bit(22) | (instr->Bits(12, 4) << 1);
290 for (
int i =
start; i <
start + reg_count; i++) {
292 if (i !=
start + reg_count - 1) {
303void ARMDecoder::PrintDRegisterList(
int start,
int reg_count) {
305 for (
int i =
start; i <
start + reg_count; i++) {
307 if (i !=
start + reg_count - 1) {
314int ARMDecoder::FormatDRegister(Instr* instr,
const char*
format) {
317 int reg = instr->DnField();
320 }
else if (
format[1] ==
'd') {
321 int reg = instr->DdField();
324 }
else if (
format[1] ==
'm') {
325 int reg = instr->DmField();
328 }
else if (
format[1] ==
'l') {
330 int reg_count = instr->Bits(0, 8) >> 1;
331 int start = (instr->Bit(22) << 4) | instr->Bits(12, 4);
332 PrintDRegisterList(
start, reg_count);
334 }
else if (
format[1] ==
't') {
336 int reg_count = instr->Bits(8, 2) + 1;
337 int start = (instr->Bit(7) << 4) | instr->Bits(16, 4);
338 PrintDRegisterList(
start, reg_count);
345int ARMDecoder::FormatQRegister(Instr* instr,
const char*
format) {
348 int reg = instr->QnField();
351 }
else if (
format[1] ==
'd') {
352 int reg = instr->QdField();
355 }
else if (
format[1] ==
'm') {
356 int reg = instr->QmField();
369int ARMDecoder::FormatOption(Instr* instr,
const char*
format) {
372 if (instr->Bit(21) == 0) {
387 PrintCondition(instr);
394 (
static_cast<uint32_t
>(instr->SImmed24Field()) << 2) + 8;
395 if (FLAG_disassemble_relative) {
398 remaining_size_in_buffer(),
"%+" Pd32 "", off);
400 uword destination =
reinterpret_cast<uword>(instr) + off;
402 remaining_size_in_buffer(),
"%#" Px "",
407 return FormatDRegister(instr,
format);
411 return FormatQRegister(instr,
format);
418 remaining_size_in_buffer(),
"%f",
419 instr->ImmFloatField());
421 }
else if (
format[3] ==
'd') {
424 remaining_size_in_buffer(),
"%g",
425 instr->ImmDoubleField());
427 }
else if (
format[3] ==
'1') {
429 immed16 = instr->BkptField();
435 int32_t imm4 = instr->Bits(16, 4);
438 else if ((imm4 & 2) != 0)
440 else if ((imm4 & 4) != 0)
443 remaining_size_in_buffer(),
"%d", idx);
447 immed16 = instr->MovwField();
452 remaining_size_in_buffer(),
"0x%x", immed16);
459 remaining_size_in_buffer(),
"%u",
460 instr->BitFieldExtractLSBField());
464 if (instr->HasLink()) {
474 ((instr->TypeField() == 0) && instr->HasSign() && !instr->HasH())) {
486 remaining_size_in_buffer(),
"%d",
487 instr->Bits(0, 8) << 2);
492 remaining_size_in_buffer(),
"%d",
493 instr->Offset12Field());
499 int offs8 = (instr->ImmedHField() << 4) | instr->ImmedLField();
501 remaining_size_in_buffer(),
"%d", offs8);
510 return FormatRegister(instr,
format);
516 if (instr->TypeField() == 0) {
519 ASSERT(instr->TypeField() == 1);
520 PrintShiftImm(instr);
528 }
else if (
format[1] ==
'v') {
531 remaining_size_in_buffer(),
"0x%x",
534 }
else if (
format[1] ==
'z') {
536 int sz = instr->Bits(20, 2);
556 remaining_size_in_buffer(),
"%s", sz_str);
558 }
else if (
format[1] ==
' ') {
565 return FormatSRegister(instr,
format);
570 int32_t off = (
static_cast<uint32_t
>(instr->SImmed24Field()) << 2) + 8;
572 remaining_size_in_buffer(),
"%+d", off);
576 if (instr->Bit(22) == 0) {
589 remaining_size_in_buffer(),
"%u",
590 instr->BitFieldExtractWidthField() + 1);
601 if (!instr->HasSign()) {
603 }
else if (instr->HasL()) {
626void ARMDecoder::Format(Instr* instr,
const char*
format) {
628 while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) {
632 buffer_[buffer_pos_++] = cur;
636 buffer_[buffer_pos_] =
'\0';
641void ARMDecoder::Unknown(Instr* instr) {
645void ARMDecoder::DecodeType01(Instr* instr) {
646 if (!instr->IsDataProcessing()) {
648 if (instr->IsMiscellaneous()) {
649 switch (instr->Bits(4, 3)) {
651 if (instr->Bits(21, 2) == 0x3) {
652 Format(instr,
"clz'cond 'rd, 'rm");
653 }
else if (instr->Bits(21, 2) == 0x1) {
654 Format(instr,
"bx'cond 'rm");
661 if (instr->Bits(21, 2) == 0x1) {
662 Format(instr,
"blx'cond 'rm");
670 if ((instr->Bits(21, 2) == 0x1) && (instr->ConditionField() ==
AL)) {
671 Format(instr,
"bkpt #'imm12_4");
683 }
else if (instr->IsMultiplyOrSyncPrimitive()) {
684 if (instr->Bit(24) == 0) {
686 switch (instr->Bits(21, 3)) {
689 Format(instr,
"mul'cond's 'rn, 'rm, 'rs");
694 Format(instr,
"mla'cond's 'rn, 'rm, 'rs, 'rd");
699 Format(instr,
"umaal'cond's 'rd, 'rn, 'rm, 'rs");
704 Format(instr,
"mls'cond's 'rn, 'rm, 'rs, 'rd");
709 Format(instr,
"umull'cond's 'rd, 'rn, 'rm, 'rs");
714 Format(instr,
"umlal'cond's 'rd, 'rn, 'rm, 'rs");
719 Format(instr,
"smull'cond's 'rd, 'rn, 'rm, 'rs");
729 switch (instr->Bits(20, 4)) {
731 Format(instr,
"strex'cond 'rd, 'rm, ['rn]");
735 Format(instr,
"ldrex'cond 'rd, ['rn]");
744 }
else if (instr->Bit(25) == 1) {
746 switch (instr->Bits(20, 5)) {
748 Format(instr,
"movw'cond 'rd, #'imm4_12");
752 if ((instr->Bits(16, 4) == 0) && (instr->Bits(0, 8) == 0)) {
753 Format(instr,
"nop'cond");
760 Format(instr,
"movt'cond 'rd, #'imm4_12");
770 switch (instr->PUField()) {
772 if (instr->Bit(22) == 0) {
773 Format(instr,
"'memop'cond'x 'rd2, ['rn], -'rm");
775 Format(instr,
"'memop'cond'x 'rd2, ['rn], #-'off8");
780 if (instr->Bit(22) == 0) {
781 Format(instr,
"'memop'cond'x 'rd2, ['rn], +'rm");
783 Format(instr,
"'memop'cond'x 'rd2, ['rn], #+'off8");
788 if (instr->Bit(22) == 0) {
789 Format(instr,
"'memop'cond'x 'rd2, ['rn, -'rm]'w");
791 Format(instr,
"'memop'cond'x 'rd2, ['rn, #-'off8]'w");
796 if (instr->Bit(22) == 0) {
797 Format(instr,
"'memop'cond'x 'rd2, ['rn, +'rm]'w");
799 Format(instr,
"'memop'cond'x 'rd2, ['rn, #+'off8]'w");
811 switch (instr->OpcodeField()) {
813 Format(instr,
"and'cond's 'rd, 'rn, 'shift_op");
817 Format(instr,
"eor'cond's 'rd, 'rn, 'shift_op");
821 Format(instr,
"sub'cond's 'rd, 'rn, 'shift_op");
825 Format(instr,
"rsb'cond's 'rd, 'rn, 'shift_op");
829 Format(instr,
"add'cond's 'rd, 'rn, 'shift_op");
833 Format(instr,
"adc'cond's 'rd, 'rn, 'shift_op");
837 Format(instr,
"sbc'cond's 'rd, 'rn, 'shift_op");
841 Format(instr,
"rsc'cond's 'rd, 'rn, 'shift_op");
846 Format(instr,
"tst'cond 'rn, 'shift_op");
854 Format(instr,
"teq'cond 'rn, 'shift_op");
862 Format(instr,
"cmp'cond 'rn, 'shift_op");
870 Format(instr,
"cmn'cond 'rn, 'shift_op");
877 Format(instr,
"orr'cond's 'rd, 'rn, 'shift_op");
881 Format(instr,
"mov'cond's 'rd, 'shift_op");
885 Format(instr,
"bic'cond's 'rd, 'rn, 'shift_op");
889 Format(instr,
"mvn'cond's 'rd, 'shift_op");
901void ARMDecoder::DecodeType2(Instr* instr) {
902 switch (instr->PUField()) {
907 Format(instr,
"'memop'cond'b 'rd, ['rn], #-'off12");
915 Format(instr,
"'memop'cond'b 'rd, ['rn], #+'off12");
920 Format(instr,
"'memop'cond'b 'rd, ['rn, #-'off12]'w");
924 Format(instr,
"'memop'cond'b 'rd, ['rn, #+'off12]'w");
935void ARMDecoder::DecodeType3(Instr* instr) {
936 if (instr->IsMedia()) {
937 if (instr->IsDivision()) {
944 "div 'rd does not correspond to 'rn");
946 "div 'rm does not correspond to 'rs");
948 "div 'rn does not correspond to 'rm");
949 if (instr->IsDivUnsigned()) {
950 Format(instr,
"udiv'cond 'rn, 'rm, 'rs");
952 Format(instr,
"sdiv'cond 'rn, 'rm, 'rs");
954 }
else if (instr->IsRbit()) {
955 Format(instr,
"rbit'cond 'rd, 'rm");
956 }
else if (instr->IsBitFieldExtract()) {
959 "bfx 'rn does not correspond to 'rm");
960 if (instr->IsBitFieldExtractSignExtended()) {
961 Format(instr,
"sbfx'cond 'rd, 'rm, 'lsb, 'width");
963 Format(instr,
"ubfx'cond 'rd, 'rm, 'lsb, 'width");
970 switch (instr->PUField()) {
975 Format(instr,
"'memop'cond'b 'rd, ['rn], -'shift_rm");
983 Format(instr,
"'memop'cond'b 'rd, ['rn], +'shift_rm");
988 Format(instr,
"'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
992 Format(instr,
"'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
1003void ARMDecoder::DecodeType4(Instr* instr) {
1004 if (instr->Bit(22) == 1) {
1006 }
else if (instr->HasL()) {
1007 Format(instr,
"ldm'cond'pu 'rn'w, 'rlist");
1009 Format(instr,
"stm'cond'pu 'rn'w, 'rlist");
1013void ARMDecoder::DecodeType5(Instr* instr) {
1014 Format(instr,
"b'l'cond 'target ; 'dest");
1017void ARMDecoder::DecodeType6(Instr* instr) {
1018 if (instr->IsVFPDoubleTransfer()) {
1019 if (instr->Bit(8) == 0) {
1020 if (instr->Bit(20) == 1) {
1021 Format(instr,
"vmovrrs'cond 'rd, 'rn, {'sm, 'sm1}");
1023 Format(instr,
"vmovsrr'cond {'sm, 'sm1}, 'rd, 'rn");
1026 if (instr->Bit(20) == 1) {
1027 Format(instr,
"vmovrrd'cond 'rd, 'rn, 'dm");
1029 Format(instr,
"vmovdrr'cond 'dm, 'rd, 'rn");
1032 }
else if (instr->IsVFPLoadStore()) {
1033 if (instr->Bit(8) == 0) {
1034 if (instr->Bit(20) == 1) {
1035 if (instr->Bit(23) == 1) {
1036 Format(instr,
"vldrs'cond 'sd, ['rn, #+'off10]");
1038 Format(instr,
"vldrs'cond 'sd, ['rn, #-'off10]");
1041 if (instr->Bit(23) == 1) {
1042 Format(instr,
"vstrs'cond 'sd, ['rn, #+'off10]");
1044 Format(instr,
"vstrs'cond 'sd, ['rn, #-'off10]");
1048 if (instr->Bit(20) == 1) {
1049 if (instr->Bit(23) == 1) {
1050 Format(instr,
"vldrd'cond 'dd, ['rn, #+'off10]");
1052 Format(instr,
"vldrd'cond 'dd, ['rn, #-'off10]");
1055 if (instr->Bit(23) == 1) {
1056 Format(instr,
"vstrd'cond 'dd, ['rn, #+'off10]");
1058 Format(instr,
"vstrd'cond 'dd, ['rn, #-'off10]");
1062 }
else if (instr->IsVFPMultipleLoadStore()) {
1063 if (instr->HasL()) {
1064 if (instr->Bit(8) != 0) {
1065 Format(instr,
"vldmd'cond'pu 'rn'w, 'dlist");
1067 Format(instr,
"vldms'cond'pu 'rn'w, 'slist");
1070 if (instr->Bit(8) != 0) {
1071 Format(instr,
"vstmd'cond'pu 'rn'w, 'dlist");
1073 Format(instr,
"vstms'cond'pu 'rn'w, 'slist");
1081void ARMDecoder::DecodeType7(Instr* instr) {
1082 if (instr->Bit(24) == 1) {
1083 Format(instr,
"svc'cond #'svc");
1084 }
else if (instr->IsVFPDataProcessingOrSingleTransfer()) {
1085 if (instr->Bit(4) == 0) {
1087 switch (instr->Bits(20, 4) & 0xb) {
1089 if (instr->Bit(8) == 0) {
1090 if (instr->Bit(6) == 0) {
1091 Format(instr,
"vmlas'cond 'sd, 'sn, 'sm");
1093 Format(instr,
"vmlss'cond 'sd, 'sn, 'sm");
1096 if (instr->Bit(6) == 0) {
1097 Format(instr,
"vmlad'cond 'dd, 'dn, 'dm");
1099 Format(instr,
"vmlsd'cond 'dd, 'dn, 'dm");
1110 if (instr->Bit(8) == 0) {
1111 Format(instr,
"vmuls'cond 'sd, 'sn, 'sm");
1113 Format(instr,
"vmuld'cond 'dd, 'dn, 'dm");
1118 if (instr->Bit(8) == 0) {
1119 Format(instr,
"vdivs'cond 'sd, 'sn, 'sm");
1121 Format(instr,
"vdivd'cond 'dd, 'dn, 'dm");
1126 if (instr->Bit(8) == 0) {
1127 if (instr->Bit(6) == 0) {
1128 Format(instr,
"vadds'cond 'sd, 'sn, 'sm");
1130 Format(instr,
"vsubs'cond 'sd, 'sn, 'sm");
1133 if (instr->Bit(6) == 0) {
1134 Format(instr,
"vaddd'cond 'dd, 'dn, 'dm");
1136 Format(instr,
"vsubd'cond 'dd, 'dn, 'dm");
1142 if (instr->Bit(6) == 0) {
1143 if (instr->Bit(8) == 0) {
1144 Format(instr,
"vmovs'cond 'sd, #'immf");
1146 Format(instr,
"vmovd'cond 'dd, #'immd");
1150 switch (instr->Bits(16, 4)) {
1152 switch (instr->Bits(6, 2)) {
1154 if (instr->Bit(8) == 0) {
1155 Format(instr,
"vmovs'cond 'sd, 'sm");
1157 Format(instr,
"vmovd'cond 'dd, 'dm");
1162 if (instr->Bit(8) == 0) {
1163 Format(instr,
"vabss'cond 'sd, 'sm");
1165 Format(instr,
"vabsd'cond 'dd, 'dm");
1177 switch (instr->Bits(6, 2)) {
1179 if (instr->Bit(8) == 0) {
1180 Format(instr,
"vnegs'cond 'sd, 'sm");
1182 Format(instr,
"vnegd'cond 'dd, 'dm");
1187 if (instr->Bit(8) == 0) {
1188 Format(instr,
"vsqrts'cond 'sd, 'sm");
1190 Format(instr,
"vsqrtd'cond 'dd, 'dm");
1203 if (instr->Bit(7) == 1) {
1206 if (instr->Bit(8) == 0) {
1207 if (instr->Bit(16) == 0) {
1208 Format(instr,
"vcmps'cond 'sd, 'sm");
1210 Format(instr,
"vcmps'cond 'sd, #0.0");
1213 if (instr->Bit(16) == 0) {
1214 Format(instr,
"vcmpd'cond 'dd, 'dm");
1216 Format(instr,
"vcmpd'cond 'dd, #0.0");
1223 if (instr->Bit(8) == 0) {
1224 Format(instr,
"vcvtds'cond 'dd, 'sm");
1226 Format(instr,
"vcvtsd'cond 'sd, 'dm");
1231 if (instr->Bit(8) == 0) {
1232 if (instr->Bit(7) == 0) {
1233 Format(instr,
"vcvtsu'cond 'sd, 'sm");
1235 Format(instr,
"vcvtsi'cond 'sd, 'sm");
1238 if (instr->Bit(7) == 0) {
1239 Format(instr,
"vcvtdu'cond 'dd, 'sm");
1241 Format(instr,
"vcvtdi'cond 'dd, 'sm");
1248 if (instr->Bit(7) == 0) {
1253 if (instr->Bit(8) == 0) {
1254 if (instr->Bit(16) == 0) {
1255 Format(instr,
"vcvtus'cond 'sd, 'sm");
1257 Format(instr,
"vcvtis'cond 'sd, 'sm");
1260 if (instr->Bit(16) == 0) {
1261 Format(instr,
"vcvtud'cond 'sd, 'dm");
1263 Format(instr,
"vcvtid'cond 'sd, 'dm");
1284 if ((instr->Bits(21, 3) == 0) && (instr->Bit(8) == 0)) {
1285 if (instr->Bit(20) == 0) {
1286 Format(instr,
"vmovs'cond 'sn, 'rd");
1288 Format(instr,
"vmovr'cond 'rd, 'sn");
1290 }
else if ((instr->Bits(22, 3) == 0) && (instr->Bit(20) == 0) &&
1291 (instr->Bit(8) == 1) && (instr->Bits(5, 2) == 0)) {
1292 if (instr->Bit(21) == 0) {
1293 Format(instr,
"vmovd'cond 'dn[0], 'rd");
1295 Format(instr,
"vmovd'cond 'dn[1], 'rd");
1297 }
else if ((instr->Bits(20, 4) == 0xf) && (instr->Bit(8) == 0)) {
1298 if (instr->Bits(12, 4) == 0xf) {
1299 Format(instr,
"vmrs'cond APSR, FPSCR");
1301 Format(instr,
"vmrs'cond 'rd, FPSCR");
1312void ARMDecoder::DecodeSIMDDataProcessing(Instr* instr) {
1314 if (instr->Bit(6) == 1) {
1315 if ((instr->Bits(8, 4) == 8) && (instr->Bit(4) == 0) &&
1316 (instr->Bits(23, 2) == 0)) {
1317 Format(instr,
"vaddq'sz 'qd, 'qn, 'qm");
1318 }
else if ((instr->Bits(8, 4) == 13) && (instr->Bit(4) == 0) &&
1319 (instr->Bits(23, 2) == 0) && (instr->Bit(21) == 0)) {
1320 Format(instr,
"vaddqs 'qd, 'qn, 'qm");
1321 }
else if ((instr->Bits(8, 4) == 8) && (instr->Bit(4) == 0) &&
1322 (instr->Bits(23, 2) == 2)) {
1323 Format(instr,
"vsubq'sz 'qd, 'qn, 'qm");
1324 }
else if ((instr->Bits(8, 4) == 13) && (instr->Bit(4) == 0) &&
1325 (instr->Bits(23, 2) == 0) && (instr->Bit(21) == 1)) {
1326 Format(instr,
"vsubqs 'qd, 'qn, 'qm");
1327 }
else if ((instr->Bits(8, 4) == 9) && (instr->Bit(4) == 1) &&
1328 (instr->Bits(23, 2) == 0)) {
1329 Format(instr,
"vmulq'sz 'qd, 'qn, 'qm");
1330 }
else if ((instr->Bits(8, 4) == 13) && (instr->Bit(4) == 1) &&
1331 (instr->Bits(23, 2) == 2) && (instr->Bit(21) == 0)) {
1332 Format(instr,
"vmulqs 'qd, 'qn, 'qm");
1333 }
else if ((instr->Bits(8, 4) == 4) && (instr->Bit(4) == 0) &&
1334 (instr->Bits(23, 5) == 4)) {
1335 Format(instr,
"vshlqi'sz 'qd, 'qm, 'qn");
1336 }
else if ((instr->Bits(8, 4) == 4) && (instr->Bit(4) == 0) &&
1337 (instr->Bits(23, 5) == 6)) {
1338 Format(instr,
"vshlqu'sz 'qd, 'qm, 'qn");
1339 }
else if ((instr->Bits(8, 4) == 1) && (instr->Bit(4) == 1) &&
1340 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 2)) {
1341 Format(instr,
"veorq 'qd, 'qn, 'qm");
1342 }
else if ((instr->Bits(8, 4) == 1) && (instr->Bit(4) == 1) &&
1343 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 0)) {
1344 Format(instr,
"vornq 'qd, 'qn, 'qm");
1345 }
else if ((instr->Bits(8, 4) == 1) && (instr->Bit(4) == 1) &&
1346 (instr->Bits(20, 2) == 2) && (instr->Bits(23, 2) == 0)) {
1347 if (instr->QmField() == instr->QnField()) {
1348 Format(instr,
"vmovq 'qd, 'qm");
1350 Format(instr,
"vorrq 'qd, 'qm");
1352 }
else if ((instr->Bits(8, 4) == 1) && (instr->Bit(4) == 1) &&
1353 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 0)) {
1354 Format(instr,
"vandq 'qd, 'qn, 'qm");
1355 }
else if ((instr->Bits(7, 5) == 11) && (instr->Bit(4) == 0) &&
1356 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 5) == 7) &&
1357 (instr->Bits(16, 4) == 0)) {
1358 Format(instr,
"vmvnq 'qd, 'qm");
1359 }
else if ((instr->Bits(8, 4) == 15) && (instr->Bit(4) == 0) &&
1360 (instr->Bits(20, 2) == 2) && (instr->Bits(23, 2) == 0)) {
1361 Format(instr,
"vminqs 'qd, 'qn, 'qm");
1362 }
else if ((instr->Bits(8, 4) == 15) && (instr->Bit(4) == 0) &&
1363 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 0)) {
1364 Format(instr,
"vmaxqs 'qd, 'qn, 'qm");
1365 }
else if ((instr->Bits(8, 4) == 7) && (instr->Bit(4) == 0) &&
1366 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) &&
1367 (instr->Bit(7) == 0) && (instr->Bits(16, 4) == 9)) {
1368 Format(instr,
"vabsqs 'qd, 'qm");
1369 }
else if ((instr->Bits(8, 4) == 7) && (instr->Bit(4) == 0) &&
1370 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) &&
1371 (instr->Bit(7) == 1) && (instr->Bits(16, 4) == 9)) {
1372 Format(instr,
"vnegqs 'qd, 'qm");
1373 }
else if ((instr->Bits(7, 5) == 10) && (instr->Bit(4) == 0) &&
1374 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) &&
1375 (instr->Bits(16, 4) == 11)) {
1376 Format(instr,
"vrecpeqs 'qd, 'qm");
1377 }
else if ((instr->Bits(8, 4) == 15) && (instr->Bit(4) == 1) &&
1378 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 0)) {
1379 Format(instr,
"vrecpsqs 'qd, 'qn, 'qm");
1380 }
else if ((instr->Bits(8, 4) == 5) && (instr->Bit(4) == 0) &&
1381 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) &&
1382 (instr->Bit(7) == 1) && (instr->Bits(16, 4) == 11)) {
1383 Format(instr,
"vrsqrteqs 'qd, 'qm");
1384 }
else if ((instr->Bits(8, 4) == 15) && (instr->Bit(4) == 1) &&
1385 (instr->Bits(20, 2) == 2) && (instr->Bits(23, 2) == 0)) {
1386 Format(instr,
"vrsqrtsqs 'qd, 'qn, 'qm");
1387 }
else if ((instr->Bits(8, 4) == 12) && (instr->Bit(4) == 0) &&
1388 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) &&
1389 (instr->Bit(7) == 0)) {
1390 int32_t imm4 = instr->Bits(16, 4);
1391 if ((imm4 & 1) != 0) {
1392 Format(instr,
"vdupb 'qd, 'dm['imm4_vdup]");
1393 }
else if ((imm4 & 2) != 0) {
1394 Format(instr,
"vduph 'qd, 'dm['imm4_vdup]");
1395 }
else if ((imm4 & 4) != 0) {
1396 Format(instr,
"vdupw 'qd, 'dm['imm4_vdup]");
1400 }
else if ((instr->Bits(8, 4) == 1) && (instr->Bit(4) == 0) &&
1401 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) &&
1402 (instr->Bit(7) == 1) && (instr->Bits(16, 4) == 10)) {
1403 Format(instr,
"vzipqw 'qd, 'qm");
1404 }
else if ((instr->Bits(8, 4) == 8) && (instr->Bit(4) == 1) &&
1405 (instr->Bits(23, 2) == 2)) {
1406 Format(instr,
"vceqq'sz 'qd, 'qn, 'qm");
1407 }
else if ((instr->Bits(8, 4) == 14) && (instr->Bit(4) == 0) &&
1408 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 0)) {
1409 Format(instr,
"vceqqs 'qd, 'qn, 'qm");
1410 }
else if ((instr->Bits(8, 4) == 3) && (instr->Bit(4) == 1) &&
1411 (instr->Bits(23, 2) == 0)) {
1412 Format(instr,
"vcgeq'sz 'qd, 'qn, 'qm");
1413 }
else if ((instr->Bits(8, 4) == 3) && (instr->Bit(4) == 1) &&
1414 (instr->Bits(23, 2) == 2)) {
1415 Format(instr,
"vcugeq'sz 'qd, 'qn, 'qm");
1416 }
else if ((instr->Bits(8, 4) == 14) && (instr->Bit(4) == 0) &&
1417 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 2)) {
1418 Format(instr,
"vcgeqs 'qd, 'qn, 'qm");
1419 }
else if ((instr->Bits(8, 4) == 3) && (instr->Bit(4) == 0) &&
1420 (instr->Bits(23, 2) == 0)) {
1421 Format(instr,
"vcgtq'sz 'qd, 'qn, 'qm");
1422 }
else if ((instr->Bits(8, 4) == 3) && (instr->Bit(4) == 0) &&
1423 (instr->Bits(23, 2) == 2)) {
1424 Format(instr,
"vcugtq'sz 'qd, 'qn, 'qm");
1425 }
else if ((instr->Bits(8, 4) == 14) && (instr->Bit(4) == 0) &&
1426 (instr->Bits(20, 2) == 2) && (instr->Bits(23, 2) == 2)) {
1427 Format(instr,
"vcgtqs 'qd, 'qn, 'qm");
1432 if ((instr->Bits(23, 2) == 3) && (instr->Bits(20, 2) == 3) &&
1433 (instr->Bits(10, 2) == 2) && (instr->Bit(4) == 0)) {
1434 Format(instr,
"vtbl 'dd, 'dtbllist, 'dm");
1441void ARMDecoder::InstructionDecode(
uword pc) {
1445 if (instr->InstructionBits() ==
static_cast<int32_t
>(0xf57ff01f)) {
1447 }
else if (instr->InstructionBits() ==
1449 Format(instr,
"dmb ish");
1451 if (instr->IsSIMDDataProcessing()) {
1452 DecodeSIMDDataProcessing(instr);
1458 switch (instr->TypeField()) {
1461 DecodeType01(instr);
1500 intptr_t human_size,
1501 int* out_instr_size,
1505 ARMDecoder decoder(human_buffer, human_size);
1506 decoder.InstructionDecode(pc);
1509 if (out_instr_size !=
nullptr) {
1515#if !defined(IS_SIMARM_HOST64)
1516 if (!
code.IsNull()) {
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
static bool rotate(const SkDCubic &cubic, int zero, int index, SkDCubic &rotPath)
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 bool integer_division_supported()
static int SNPrint(char *str, size_t size, const char *format,...) PRINTF_ATTRIBUTE(3
static T RotateRight(T value, uint8_t rotate)
static const uint8_t buffer[]
uint32_t uint32_t * format
constexpr uword kDataMemoryBarrier
bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code &code, Object *obj)
@ kBitFieldExtractRnShift
const char *const cpu_reg_names[kNumberOfCpuRegisters]
Format(template, **parameters)