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()) {
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)
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]
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)