31 #if V8_TARGET_ARCH_ARM 33 #include "src/arm/constants-arm.h" 34 #include "src/base/bits.h" 35 #include "src/base/platform/platform.h" 36 #include "src/disasm.h" 37 #include "src/macro-assembler.h" 50 Vector<char> out_buffer)
51 : converter_(converter),
52 out_buffer_(out_buffer),
54 out_buffer_[out_buffer_pos_] =
'\0';
61 int InstructionDecode(byte* instruction);
63 static bool IsConstantPoolAt(byte* instr_ptr);
64 static int ConstantPoolSizeAt(byte* instr_ptr);
68 void PrintChar(
const char ch);
69 void Print(
const char* str);
72 void PrintRegister(
int reg);
73 void PrintSRegister(
int reg);
74 void PrintDRegister(
int reg);
75 int FormatVFPRegister(Instruction* instr,
const char* format);
76 void PrintMovwMovt(Instruction* instr);
77 int FormatVFPinstruction(Instruction* instr,
const char* format);
78 void PrintCondition(Instruction* instr);
79 void PrintShiftRm(Instruction* instr);
80 void PrintShiftImm(Instruction* instr);
81 void PrintShiftSat(Instruction* instr);
82 void PrintPU(Instruction* instr);
83 void PrintSoftwareInterrupt(SoftwareInterruptCodes svc);
86 int FormatRegister(Instruction* instr,
const char* option);
87 void FormatNeonList(
int Vd,
int type);
88 void FormatNeonMemory(
int Rn,
int align,
int Rm);
89 int FormatOption(Instruction* instr,
const char* option);
90 void Format(Instruction* instr,
const char* format);
91 void Unknown(Instruction* instr);
97 void DecodeType01(Instruction* instr);
98 void DecodeType2(Instruction* instr);
99 void DecodeType3(Instruction* instr);
100 void DecodeType4(Instruction* instr);
101 void DecodeType5(Instruction* instr);
102 void DecodeType6(Instruction* instr);
104 int DecodeType7(Instruction* instr);
106 void DecodeTypeCP15(Instruction* instr);
108 void DecodeTypeVFP(Instruction* instr);
109 void DecodeType6CoprocessorIns(Instruction* instr);
111 void DecodeSpecialCondition(Instruction* instr);
113 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr);
114 void DecodeVCMP(Instruction* instr);
115 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr);
116 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr);
119 Vector<char> out_buffer_;
122 DISALLOW_COPY_AND_ASSIGN(Decoder);
127 #define STRING_STARTS_WITH(string, compare_string) \ 128 (strncmp(string, compare_string, strlen(compare_string)) == 0) 132 void Decoder::PrintChar(
const char ch) {
133 out_buffer_[out_buffer_pos_++] = ch;
138 void Decoder::Print(
const char* str) {
140 while (cur !=
'\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
144 out_buffer_[out_buffer_pos_] = 0;
150 static const char*
const cond_names[kNumberOfConditions] = {
151 "eq",
"ne",
"cs" ,
"cc" ,
"mi" ,
"pl" ,
"vs" ,
"vc" ,
152 "hi",
"ls",
"ge",
"lt",
"gt",
"le",
"",
"invalid",
157 void Decoder::PrintCondition(Instruction* instr) {
158 Print(cond_names[instr->ConditionValue()]);
163 void Decoder::PrintRegister(
int reg) {
164 Print(converter_.NameOfCPURegister(reg));
169 void Decoder::PrintSRegister(
int reg) {
170 Print(VFPRegisters::Name(reg,
false));
175 void Decoder::PrintDRegister(
int reg) {
176 Print(VFPRegisters::Name(reg,
true));
182 static const char*
const shift_names[kNumberOfShifts] = {
183 "lsl",
"lsr",
"asr",
"ror" 189 void Decoder::PrintShiftRm(Instruction* instr) {
190 ShiftOp shift = instr->ShiftField();
191 int shift_index = instr->ShiftValue();
192 int shift_amount = instr->ShiftAmountValue();
193 int rm = instr->RmValue();
197 if ((instr->RegShiftValue() == 0) && (shift == LSL) && (shift_amount == 0)) {
201 if (instr->RegShiftValue() == 0) {
203 if ((shift == ROR) && (shift_amount == 0)) {
206 }
else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
209 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
211 shift_names[shift_index],
215 int rs = instr->RsValue();
216 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
217 ", %s ", shift_names[shift_index]);
225 void Decoder::PrintShiftImm(Instruction* instr) {
226 int rotate = instr->RotateValue() * 2;
227 int immed8 = instr->Immed8Value();
228 int imm = base::bits::RotateRight32(immed8, rotate);
229 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"#%d", imm);
234 void Decoder::PrintShiftSat(Instruction* instr) {
235 int shift = instr->Bits(11, 7);
237 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
239 shift_names[instr->Bit(6) * 2],
246 void Decoder::PrintPU(Instruction* instr) {
247 switch (instr->PUField()) {
274 void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
276 case kCallRtRedirected:
277 Print(
"call rt redirected");
283 if (svc >= kStopCode) {
284 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
287 svc & kStopCodeMask);
289 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
300 int Decoder::FormatRegister(Instruction* instr,
const char* format) {
301 DCHECK_EQ(format[0],
'r');
302 if (format[1] ==
'n') {
303 int reg = instr->RnValue();
306 }
else if (format[1] ==
'd') {
307 int reg = instr->RdValue();
310 }
else if (format[1] ==
's') {
311 int reg = instr->RsValue();
314 }
else if (format[1] ==
'm') {
315 int reg = instr->RmValue();
318 }
else if (format[1] ==
't') {
319 int reg = instr->RtValue();
322 }
else if (format[1] ==
'l') {
324 DCHECK(STRING_STARTS_WITH(format,
"rlist"));
325 int rlist = instr->RlistValue();
330 if ((rlist & 1) != 0) {
332 if ((rlist >> 1) != 0) {
348 int Decoder::FormatVFPRegister(Instruction* instr,
const char* format) {
349 DCHECK((format[0] ==
'S') || (format[0] ==
'D'));
351 VFPRegPrecision precision =
352 format[0] ==
'D' ? kDoublePrecision : kSinglePrecision;
356 if (format[1] ==
'n') {
357 reg = instr->VFPNRegValue(precision);
358 }
else if (format[1] ==
'm') {
359 reg = instr->VFPMRegValue(precision);
360 }
else if (format[1] ==
'd') {
361 if ((instr->TypeValue() == 7) &&
362 (instr->Bit(24) == 0x0) &&
363 (instr->Bits(11, 9) == 0x5) &&
364 (instr->Bit(4) == 0x1)) {
366 reg = instr->Bits(19, 16) | (instr->Bit(7) << 4);
368 reg = instr->VFPDRegValue(precision);
371 if (format[2] ==
'+') {
372 int immed8 = instr->Immed8Value();
373 if (format[0] ==
'S') reg += immed8 - 1;
374 if (format[0] ==
'D') reg += (immed8 / 2 - 1);
376 if (format[2] ==
'+') retval = 3;
381 if (precision == kSinglePrecision) {
391 int Decoder::FormatVFPinstruction(Instruction* instr,
const char* format) {
397 void Decoder::FormatNeonList(
int Vd,
int type) {
399 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
401 }
else if (type == nlt_2) {
402 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
403 "{d%d, d%d}", Vd, Vd + 1);
404 }
else if (type == nlt_3) {
405 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
406 "{d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2);
407 }
else if (type == nlt_4) {
408 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
409 "{d%d, d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2, Vd + 3);
414 void Decoder::FormatNeonMemory(
int Rn,
int align,
int Rm) {
415 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"[%s",
416 converter_.NameOfCPURegister(Rn));
418 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
419 ":%d", (1 << align) << 6);
423 }
else if (Rm == 13) {
426 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"], %s",
427 converter_.NameOfCPURegister(Rm));
433 void Decoder::PrintMovwMovt(Instruction* instr) {
434 int imm = instr->ImmedMovwMovtValue();
435 int rd = instr->RdValue();
437 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
", #%d", imm);
446 int Decoder::FormatOption(Instruction* instr,
const char* format) {
449 if (instr->Bit(21) == 0) {
463 DCHECK(STRING_STARTS_WITH(format,
"cond"));
464 PrintCondition(instr);
468 double d = instr->DoubleImmedVmov().get_scalar();
469 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"#%g", d);
473 uint32_t lsbit = instr->Bits(11, 7);
474 uint32_t width = instr->Bits(20, 16) + 1;
475 if (instr->Bit(21) == 0) {
481 DCHECK_LE(width + lsbit, 32);
482 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
483 "#%d, #%d", lsbit, width);
496 int width = (format[3] -
'0') * 10 + (format[4] -
'0');
497 int lsb = (format[6] -
'0') * 10 + (format[7] -
'0');
499 DCHECK((width >= 1) && (width <= 32));
500 DCHECK((lsb >= 0) && (lsb <= 31));
501 DCHECK_LE(width + lsb, 32);
503 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
505 instr->Bits(width + lsb - 1, lsb));
509 if (instr->HasLink()) {
515 if (format[1] ==
'w') {
517 PrintMovwMovt(instr);
520 if (format[1] ==
'e') {
521 DCHECK(STRING_STARTS_WITH(format,
"memop"));
525 if ((instr->Bits(27, 25) == 0) && (instr->Bit(20) == 0) &&
526 (instr->Bits(7, 6) == 3) && (instr->Bit(4) == 1)) {
527 if (instr->Bit(5) == 1) {
539 DCHECK(STRING_STARTS_WITH(format,
"msg"));
541 reinterpret_cast<byte*
>(instr->InstructionBits() & 0x0FFFFFFF);
542 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
543 "%s", converter_.NameInCode(str));
547 if ((format[3] ==
'1') && (format[4] ==
'2')) {
549 DCHECK(STRING_STARTS_WITH(format,
"off12"));
550 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
551 "%d", instr->Offset12Value());
553 }
else if (format[3] ==
'0') {
555 DCHECK(STRING_STARTS_WITH(format,
"off0to3and8to19"));
556 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
558 (instr->Bits(19, 8) << 4) +
563 DCHECK(STRING_STARTS_WITH(format,
"off8"));
564 int offs8 = (instr->ImmedHValue() << 4) | instr->ImmedLValue();
565 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", offs8);
569 DCHECK(STRING_STARTS_WITH(format,
"pu"));
574 return FormatRegister(instr, format);
577 if (format[1] ==
'h') {
578 if (format[6] ==
'o') {
579 DCHECK(STRING_STARTS_WITH(format,
"shift_op"));
580 if (instr->TypeValue() == 0) {
583 DCHECK_EQ(instr->TypeValue(), 1);
584 PrintShiftImm(instr);
587 }
else if (format[6] ==
's') {
588 DCHECK(STRING_STARTS_WITH(format,
"shift_sat"));
589 PrintShiftSat(instr);
592 DCHECK(STRING_STARTS_WITH(format,
"shift_rm"));
596 }
else if (format[1] ==
'v') {
597 DCHECK(STRING_STARTS_WITH(format,
"svc"));
598 PrintSoftwareInterrupt(instr->SvcValue());
600 }
else if (format[1] ==
'i') {
601 DCHECK(STRING_STARTS_WITH(format,
"sign"));
602 if (instr->HasSign()) {
606 }
else if (format[1] ==
'p') {
607 if (format[8] ==
'_') {
608 DCHECK(STRING_STARTS_WITH(format,
"spec_reg_fields"));
610 int mask = instr->Bits(19, 16);
611 if (mask == 0) Print(
"(none)");
612 if ((mask & 0x8) != 0) Print(
"f");
613 if ((mask & 0x4) != 0) Print(
"s");
614 if ((mask & 0x2) != 0) Print(
"x");
615 if ((mask & 0x1) != 0) Print(
"c");
618 DCHECK(STRING_STARTS_WITH(format,
"spec_reg"));
619 if (instr->Bit(22) == 0) {
634 DCHECK(STRING_STARTS_WITH(format,
"target"));
635 int off = (instr->SImmed24Value() << 2) + 8;
636 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
639 converter_.NameOfAddress(
640 reinterpret_cast<byte*>(instr) + off));
656 if (instr->Bit(22) == 0) {
664 return FormatVFPinstruction(instr, format);
668 int offset = instr->Offset12Value();
669 byte* pc =
reinterpret_cast<byte*
>(instr) + Instruction::kPcLoadDelta;
671 switch (instr->PUField()) {
686 SNPrintF(out_buffer_ + out_buffer_pos_,
"0x%08" PRIxPTR,
687 reinterpret_cast<uintptr_t>(addr));
692 return FormatVFPRegister(instr, format);
712 void Decoder::Format(Instruction* instr,
const char* format) {
713 char cur = *format++;
714 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
716 format += FormatOption(instr, format);
718 out_buffer_[out_buffer_pos_++] = cur;
722 out_buffer_[out_buffer_pos_] =
'\0';
728 #define VERIFY(condition) \ 737 void Decoder::Unknown(Instruction* instr) {
738 Format(instr,
"unknown");
742 void Decoder::DecodeType01(Instruction* instr) {
743 int type = instr->TypeValue();
744 if ((type == 0) && instr->IsSpecialType0()) {
746 if (instr->Bits(7, 4) == 9) {
747 if (instr->Bit(24) == 0) {
749 if (instr->Bit(23) == 0) {
750 if (instr->Bit(21) == 0) {
754 Format(instr,
"mul'cond's 'rn, 'rm, 'rs");
756 if (instr->Bit(22) == 0) {
761 Format(instr,
"mla'cond's 'rn, 'rm, 'rs, 'rd");
767 Format(instr,
"mls'cond's 'rn, 'rm, 'rs, 'rd");
777 Format(instr,
"'um'al'cond's 'rd, 'rn, 'rm, 'rs");
780 if (instr->Bits(24, 23) == 3) {
781 if (instr->Bit(20) == 1) {
783 switch (instr->Bits(22, 21)) {
785 Format(instr,
"ldrex'cond 'rt, ['rn]");
788 Format(instr,
"ldrexd'cond 'rt, ['rn]");
791 Format(instr,
"ldrexb'cond 'rt, ['rn]");
794 Format(instr,
"ldrexh'cond 'rt, ['rn]");
804 switch (instr->Bits(22, 21)) {
806 Format(instr,
"strex'cond 'rd, 'rm, ['rn]");
809 Format(instr,
"strexd'cond 'rd, 'rm, ['rn]");
812 Format(instr,
"strexb'cond 'rd, 'rm, ['rn]");
815 Format(instr,
"strexh'cond 'rd, 'rm, ['rn]");
826 }
else if ((instr->Bit(20) == 0) && ((instr->Bits(7, 4) & 0xD) == 0xD)) {
828 switch (instr->PUField()) {
830 if (instr->Bit(22) == 0) {
831 Format(instr,
"'memop'cond's 'rd, ['rn], -'rm");
833 Format(instr,
"'memop'cond's 'rd, ['rn], #-'off8");
838 if (instr->Bit(22) == 0) {
839 Format(instr,
"'memop'cond's 'rd, ['rn], +'rm");
841 Format(instr,
"'memop'cond's 'rd, ['rn], #+'off8");
846 if (instr->Bit(22) == 0) {
847 Format(instr,
"'memop'cond's 'rd, ['rn, -'rm]'w");
849 Format(instr,
"'memop'cond's 'rd, ['rn, #-'off8]'w");
854 if (instr->Bit(22) == 0) {
855 Format(instr,
"'memop'cond's 'rd, ['rn, +'rm]'w");
857 Format(instr,
"'memop'cond's 'rd, ['rn, #+'off8]'w");
869 switch (instr->PUField()) {
871 if (instr->Bit(22) == 0) {
872 Format(instr,
"'memop'cond'sign'h 'rd, ['rn], -'rm");
874 Format(instr,
"'memop'cond'sign'h 'rd, ['rn], #-'off8");
879 if (instr->Bit(22) == 0) {
880 Format(instr,
"'memop'cond'sign'h 'rd, ['rn], +'rm");
882 Format(instr,
"'memop'cond'sign'h 'rd, ['rn], #+'off8");
887 if (instr->Bit(22) == 0) {
888 Format(instr,
"'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
890 Format(instr,
"'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");
895 if (instr->Bit(22) == 0) {
896 Format(instr,
"'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
898 Format(instr,
"'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");
910 }
else if ((type == 0) && instr->IsMiscType0()) {
911 if ((instr->Bits(27, 23) == 2) && (instr->Bits(21, 20) == 2) &&
912 (instr->Bits(15, 4) == 0xF00)) {
913 Format(instr,
"msr'cond 'spec_reg'spec_reg_fields, 'rm");
914 }
else if ((instr->Bits(27, 23) == 2) && (instr->Bits(21, 20) == 0) &&
915 (instr->Bits(11, 0) == 0)) {
916 Format(instr,
"mrs'cond 'rd, 'spec_reg");
917 }
else if (instr->Bits(22, 21) == 1) {
918 switch (instr->BitField(7, 4)) {
920 Format(instr,
"bx'cond 'rm");
923 Format(instr,
"blx'cond 'rm");
926 Format(instr,
"bkpt 'off0to3and8to19");
932 }
else if (instr->Bits(22, 21) == 3) {
933 switch (instr->BitField(7, 4)) {
935 Format(instr,
"clz'cond 'rd, 'rm");
944 }
else if ((type == 1) && instr->IsNopLikeType1()) {
945 if (instr->BitField(7, 0) == 0) {
946 Format(instr,
"nop'cond");
947 }
else if (instr->BitField(7, 0) == 20) {
948 Format(instr,
"csdb");
953 switch (instr->OpcodeField()) {
955 Format(instr,
"and'cond's 'rd, 'rn, 'shift_op");
959 Format(instr,
"eor'cond's 'rd, 'rn, 'shift_op");
963 Format(instr,
"sub'cond's 'rd, 'rn, 'shift_op");
967 Format(instr,
"rsb'cond's 'rd, 'rn, 'shift_op");
971 Format(instr,
"add'cond's 'rd, 'rn, 'shift_op");
975 Format(instr,
"adc'cond's 'rd, 'rn, 'shift_op");
979 Format(instr,
"sbc'cond's 'rd, 'rn, 'shift_op");
983 Format(instr,
"rsc'cond's 'rd, 'rn, 'shift_op");
988 Format(instr,
"tst'cond 'rn, 'shift_op");
990 Format(instr,
"movw'cond 'mw");
996 Format(instr,
"teq'cond 'rn, 'shift_op");
1005 if (instr->HasS()) {
1006 Format(instr,
"cmp'cond 'rn, 'shift_op");
1008 Format(instr,
"movt'cond 'mw");
1013 if (instr->HasS()) {
1014 Format(instr,
"cmn'cond 'rn, 'shift_op");
1023 Format(instr,
"orr'cond's 'rd, 'rn, 'shift_op");
1027 Format(instr,
"mov'cond's 'rd, 'shift_op");
1031 Format(instr,
"bic'cond's 'rd, 'rn, 'shift_op");
1035 Format(instr,
"mvn'cond's 'rd, 'shift_op");
1048 void Decoder::DecodeType2(Instruction* instr) {
1049 switch (instr->PUField()) {
1051 if (instr->HasW()) {
1055 Format(instr,
"'memop'cond'b 'rd, ['rn], #-'off12");
1059 if (instr->HasW()) {
1063 Format(instr,
"'memop'cond'b 'rd, ['rn], #+'off12");
1067 if (instr->HasL() && (instr->RnValue() == kPCRegister)) {
1068 Format(instr,
"'memop'cond'b 'rd, [pc, #-'off12]'w (addr 'A)");
1070 Format(instr,
"'memop'cond'b 'rd, ['rn, #-'off12]'w");
1075 if (instr->HasL() && (instr->RnValue() == kPCRegister)) {
1076 Format(instr,
"'memop'cond'b 'rd, [pc, #+'off12]'w (addr 'A)");
1078 Format(instr,
"'memop'cond'b 'rd, ['rn, #+'off12]'w");
1091 void Decoder::DecodeType3(Instruction* instr) {
1092 switch (instr->PUField()) {
1094 VERIFY(!instr->HasW());
1095 Format(instr,
"'memop'cond'b 'rd, ['rn], -'shift_rm");
1099 if (instr->Bit(4) == 0) {
1100 Format(instr,
"'memop'cond'b 'rd, ['rn], +'shift_rm");
1102 if (instr->Bit(5) == 0) {
1103 switch (instr->Bits(22, 21)) {
1105 if (instr->Bit(20) == 0) {
1106 if (instr->Bit(6) == 0) {
1107 Format(instr,
"pkhbt'cond 'rd, 'rn, 'rm, lsl #'imm05@07");
1109 if (instr->Bits(11, 7) == 0) {
1110 Format(instr,
"pkhtb'cond 'rd, 'rn, 'rm, asr #32");
1112 Format(instr,
"pkhtb'cond 'rd, 'rn, 'rm, asr #'imm05@07");
1126 Format(instr,
"usat 'rd, #'imm05@16, 'rm'shift_sat");
1130 switch (instr->Bits(22, 21)) {
1135 if (instr->Bits(9, 6) == 1) {
1136 if (instr->Bit(20) == 0) {
1137 if (instr->Bits(19, 16) == 0xF) {
1138 switch (instr->Bits(11, 10)) {
1140 Format(instr,
"sxtb'cond 'rd, 'rm");
1143 Format(instr,
"sxtb'cond 'rd, 'rm, ror #8");
1146 Format(instr,
"sxtb'cond 'rd, 'rm, ror #16");
1149 Format(instr,
"sxtb'cond 'rd, 'rm, ror #24");
1153 switch (instr->Bits(11, 10)) {
1155 Format(instr,
"sxtab'cond 'rd, 'rn, 'rm");
1158 Format(instr,
"sxtab'cond 'rd, 'rn, 'rm, ror #8");
1161 Format(instr,
"sxtab'cond 'rd, 'rn, 'rm, ror #16");
1164 Format(instr,
"sxtab'cond 'rd, 'rn, 'rm, ror #24");
1169 if (instr->Bits(19, 16) == 0xF) {
1170 switch (instr->Bits(11, 10)) {
1172 Format(instr,
"sxth'cond 'rd, 'rm");
1175 Format(instr,
"sxth'cond 'rd, 'rm, ror #8");
1178 Format(instr,
"sxth'cond 'rd, 'rm, ror #16");
1181 Format(instr,
"sxth'cond 'rd, 'rm, ror #24");
1185 switch (instr->Bits(11, 10)) {
1187 Format(instr,
"sxtah'cond 'rd, 'rn, 'rm");
1190 Format(instr,
"sxtah'cond 'rd, 'rn, 'rm, ror #8");
1193 Format(instr,
"sxtah'cond 'rd, 'rn, 'rm, ror #16");
1196 Format(instr,
"sxtah'cond 'rd, 'rn, 'rm, ror #24");
1201 }
else if (instr->Bits(27, 16) == 0x6BF &&
1202 instr->Bits(11, 4) == 0xF3) {
1203 Format(instr,
"rev'cond 'rd, 'rm");
1209 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
1210 if (instr->Bits(19, 16) == 0xF) {
1211 switch (instr->Bits(11, 10)) {
1213 Format(instr,
"uxtb16'cond 'rd, 'rm");
1216 Format(instr,
"uxtb16'cond 'rd, 'rm, ror #8");
1219 Format(instr,
"uxtb16'cond 'rd, 'rm, ror #16");
1222 Format(instr,
"uxtb16'cond 'rd, 'rm, ror #24");
1233 if ((instr->Bits(9, 6) == 1)) {
1234 if ((instr->Bit(20) == 0)) {
1235 if (instr->Bits(19, 16) == 0xF) {
1236 switch (instr->Bits(11, 10)) {
1238 Format(instr,
"uxtb'cond 'rd, 'rm");
1241 Format(instr,
"uxtb'cond 'rd, 'rm, ror #8");
1244 Format(instr,
"uxtb'cond 'rd, 'rm, ror #16");
1247 Format(instr,
"uxtb'cond 'rd, 'rm, ror #24");
1251 switch (instr->Bits(11, 10)) {
1253 Format(instr,
"uxtab'cond 'rd, 'rn, 'rm");
1256 Format(instr,
"uxtab'cond 'rd, 'rn, 'rm, ror #8");
1259 Format(instr,
"uxtab'cond 'rd, 'rn, 'rm, ror #16");
1262 Format(instr,
"uxtab'cond 'rd, 'rn, 'rm, ror #24");
1267 if (instr->Bits(19, 16) == 0xF) {
1268 switch (instr->Bits(11, 10)) {
1270 Format(instr,
"uxth'cond 'rd, 'rm");
1273 Format(instr,
"uxth'cond 'rd, 'rm, ror #8");
1276 Format(instr,
"uxth'cond 'rd, 'rm, ror #16");
1279 Format(instr,
"uxth'cond 'rd, 'rm, ror #24");
1283 switch (instr->Bits(11, 10)) {
1285 Format(instr,
"uxtah'cond 'rd, 'rn, 'rm");
1288 Format(instr,
"uxtah'cond 'rd, 'rn, 'rm, ror #8");
1291 Format(instr,
"uxtah'cond 'rd, 'rn, 'rm, ror #16");
1294 Format(instr,
"uxtah'cond 'rd, 'rn, 'rm, ror #24");
1301 if ((instr->Bits(20, 16) == 0x1F) &&
1302 (instr->Bits(11, 4) == 0xF3)) {
1303 Format(instr,
"rbit'cond 'rd, 'rm");
1315 if (instr->Bits(22, 20) == 0x5) {
1316 if (instr->Bits(7, 4) == 0x1) {
1317 if (instr->Bits(15, 12) == 0xF) {
1318 Format(instr,
"smmul'cond 'rn, 'rm, 'rs");
1321 Format(instr,
"smmla'cond 'rn, 'rm, 'rs, 'rd");
1326 if (instr->Bits(5, 4) == 0x1) {
1327 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) {
1328 if (instr->Bit(21) == 0x1) {
1330 Format(instr,
"udiv'cond'b 'rn, 'rm, 'rs");
1333 Format(instr,
"sdiv'cond'b 'rn, 'rm, 'rs");
1338 Format(instr,
"'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
1342 if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) {
1345 uint32_t msbit = widthminus1 + lsbit;
1347 if (instr->Bit(22)) {
1348 Format(instr,
"ubfx'cond 'rd, 'rm, 'f");
1350 Format(instr,
"sbfx'cond 'rd, 'rm, 'f");
1355 }
else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) {
1358 if (msbit >= lsbit) {
1359 if (instr->RmValue() == 15) {
1360 Format(instr,
"bfc'cond 'rd, 'f");
1362 Format(instr,
"bfi'cond 'rd, 'rm, 'f");
1368 Format(instr,
"'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
1381 void Decoder::DecodeType4(Instruction* instr) {
1382 if (instr->Bit(22) != 0) {
1386 if (instr->HasL()) {
1387 Format(instr,
"ldm'cond'pu 'rn'w, 'rlist");
1389 Format(instr,
"stm'cond'pu 'rn'w, 'rlist");
1395 void Decoder::DecodeType5(Instruction* instr) {
1396 Format(instr,
"b'l'cond 'target");
1400 void Decoder::DecodeType6(Instruction* instr) {
1401 DecodeType6CoprocessorIns(instr);
1405 int Decoder::DecodeType7(Instruction* instr) {
1406 if (instr->Bit(24) == 1) {
1407 if (instr->SvcValue() >= kStopCode) {
1408 Format(instr,
"stop'cond 'svc");
1410 Format(instr,
"svc'cond 'svc");
1413 switch (instr->CoprocessorValue()) {
1416 DecodeTypeVFP(instr);
1419 DecodeTypeCP15(instr);
1461 void Decoder::DecodeTypeVFP(Instruction* instr) {
1462 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
1463 VERIFY(instr->Bits(11, 9) == 0x5);
1465 if (instr->Bit(4) == 0) {
1466 if (instr->Opc1Value() == 0x7) {
1468 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
1470 if (instr->SzValue() == 0x1) {
1471 Format(instr,
"vmov'cond.f64 'Dd, 'Dm");
1473 Format(instr,
"vmov'cond.f32 'Sd, 'Sm");
1475 }
else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) {
1477 if (instr->SzValue() == 0x1) {
1478 Format(instr,
"vabs'cond.f64 'Dd, 'Dm");
1480 Format(instr,
"vabs'cond.f32 'Sd, 'Sm");
1482 }
else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) {
1484 if (instr->SzValue() == 0x1) {
1485 Format(instr,
"vneg'cond.f64 'Dd, 'Dm");
1487 Format(instr,
"vneg'cond.f32 'Sd, 'Sm");
1489 }
else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
1490 DecodeVCVTBetweenDoubleAndSingle(instr);
1491 }
else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
1492 DecodeVCVTBetweenFloatingPointAndInteger(instr);
1493 }
else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) &&
1494 (instr->Bit(8) == 1)) {
1496 int fraction_bits = 32 - ((instr->Bits(3, 0) << 1) | instr->Bit(5));
1497 Format(instr,
"vcvt'cond.f64.s32 'Dd, 'Dd");
1498 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1499 ", #%d", fraction_bits);
1500 }
else if (((instr->Opc2Value() >> 1) == 0x6) &&
1501 (instr->Opc3Value() & 0x1)) {
1502 DecodeVCVTBetweenFloatingPointAndInteger(instr);
1503 }
else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
1504 (instr->Opc3Value() & 0x1)) {
1506 }
else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
1507 if (instr->SzValue() == 0x1) {
1508 Format(instr,
"vsqrt'cond.f64 'Dd, 'Dm");
1510 Format(instr,
"vsqrt'cond.f32 'Sd, 'Sm");
1512 }
else if (instr->Opc3Value() == 0x0) {
1513 if (instr->SzValue() == 0x1) {
1514 Format(instr,
"vmov'cond.f64 'Dd, 'd");
1516 Format(instr,
"vmov'cond.f32 'Sd, 'd");
1518 }
else if (((instr->Opc2Value() == 0x6)) && instr->Opc3Value() == 0x3) {
1520 if (instr->SzValue() == 0x1) {
1521 Format(instr,
"vrintz'cond.f64.f64 'Dd, 'Dm");
1523 Format(instr,
"vrintz'cond.f32.f32 'Sd, 'Sm");
1528 }
else if (instr->Opc1Value() == 0x3) {
1529 if (instr->SzValue() == 0x1) {
1530 if (instr->Opc3Value() & 0x1) {
1531 Format(instr,
"vsub'cond.f64 'Dd, 'Dn, 'Dm");
1533 Format(instr,
"vadd'cond.f64 'Dd, 'Dn, 'Dm");
1536 if (instr->Opc3Value() & 0x1) {
1537 Format(instr,
"vsub'cond.f32 'Sd, 'Sn, 'Sm");
1539 Format(instr,
"vadd'cond.f32 'Sd, 'Sn, 'Sm");
1542 }
else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
1543 if (instr->SzValue() == 0x1) {
1544 Format(instr,
"vmul'cond.f64 'Dd, 'Dn, 'Dm");
1546 Format(instr,
"vmul'cond.f32 'Sd, 'Sn, 'Sm");
1548 }
else if ((instr->Opc1Value() == 0x0) && !(instr->Opc3Value() & 0x1)) {
1549 if (instr->SzValue() == 0x1) {
1550 Format(instr,
"vmla'cond.f64 'Dd, 'Dn, 'Dm");
1552 Format(instr,
"vmla'cond.f32 'Sd, 'Sn, 'Sm");
1554 }
else if ((instr->Opc1Value() == 0x0) && (instr->Opc3Value() & 0x1)) {
1555 if (instr->SzValue() == 0x1) {
1556 Format(instr,
"vmls'cond.f64 'Dd, 'Dn, 'Dm");
1558 Format(instr,
"vmls'cond.f32 'Sd, 'Sn, 'Sm");
1560 }
else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
1561 if (instr->SzValue() == 0x1) {
1562 Format(instr,
"vdiv'cond.f64 'Dd, 'Dn, 'Dm");
1564 Format(instr,
"vdiv'cond.f32 'Sd, 'Sn, 'Sm");
1570 if ((instr->VCValue() == 0x0) &&
1571 (instr->VAValue() == 0x0)) {
1572 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
1573 }
else if ((instr->VLValue() == 0x0) && (instr->VCValue() == 0x1)) {
1574 const char* rt_name = converter_.NameOfCPURegister(instr->RtValue());
1575 if (instr->Bit(23) == 0) {
1576 int opc1_opc2 = (instr->Bits(22, 21) << 2) | instr->Bits(6, 5);
1577 if ((opc1_opc2 & 0xB) == 0) {
1579 if (instr->Bit(21) == 0x0) {
1580 Format(instr,
"vmov'cond.32 'Dd[0], 'rt");
1582 Format(instr,
"vmov'cond.32 'Dd[1], 'rt");
1585 int vd = instr->VFPNRegValue(kDoublePrecision);
1586 if ((opc1_opc2 & 0x8) != 0) {
1588 int i = opc1_opc2 & 0x7;
1589 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1590 "vmov.8 d%d[%d], %s", vd,
i, rt_name);
1591 }
else if ((opc1_opc2 & 0x1) != 0) {
1593 int i = (opc1_opc2 >> 1) & 0x3;
1594 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1595 "vmov.16 d%d[%d], %s", vd,
i, rt_name);
1602 if (instr->Bit(5) != 0) {
1604 }
else if (instr->Bit(22) != 0) {
1607 int Vd = instr->VFPNRegValue(kSimd128Precision);
1608 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1609 "vdup.%i q%d, %s", size, Vd, rt_name);
1611 }
else if ((instr->VLValue() == 0x1) && (instr->VCValue() == 0x1)) {
1612 int opc1_opc2 = (instr->Bits(22, 21) << 2) | instr->Bits(6, 5);
1613 if ((opc1_opc2 & 0xB) == 0) {
1615 if (instr->Bit(21) == 0x0) {
1616 Format(instr,
"vmov'cond.32 'rt, 'Dd[0]");
1618 Format(instr,
"vmov'cond.32 'rt, 'Dd[1]");
1621 char sign = instr->Bit(23) != 0 ?
'u' :
's';
1622 const char* rt_name = converter_.NameOfCPURegister(instr->RtValue());
1623 int vn = instr->VFPNRegValue(kDoublePrecision);
1624 if ((opc1_opc2 & 0x8) != 0) {
1626 int i = opc1_opc2 & 0x7;
1628 SNPrintF(out_buffer_ + out_buffer_pos_,
"vmov.%c8 %s, d%d[%d]",
1629 sign, rt_name, vn,
i);
1630 }
else if ((opc1_opc2 & 0x1) != 0) {
1632 int i = (opc1_opc2 >> 1) & 0x3;
1634 SNPrintF(out_buffer_ + out_buffer_pos_,
"vmov.%c16 %s, d%d[%d]",
1635 sign, rt_name, vn,
i);
1640 }
else if ((instr->VCValue() == 0x0) &&
1641 (instr->VAValue() == 0x7) &&
1642 (instr->Bits(19, 16) == 0x1)) {
1643 if (instr->VLValue() == 0) {
1644 if (instr->Bits(15, 12) == 0xF) {
1645 Format(instr,
"vmsr'cond FPSCR, APSR");
1647 Format(instr,
"vmsr'cond FPSCR, 'rt");
1650 if (instr->Bits(15, 12) == 0xF) {
1651 Format(instr,
"vmrs'cond APSR, FPSCR");
1653 Format(instr,
"vmrs'cond 'rt, FPSCR");
1662 void Decoder::DecodeTypeCP15(Instruction* instr) {
1663 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0));
1664 VERIFY(instr->CoprocessorValue() == 15);
1666 if (instr->Bit(4) == 1) {
1667 int crn = instr->Bits(19, 16);
1668 int crm = instr->Bits(3, 0);
1669 int opc1 = instr->Bits(23, 21);
1670 int opc2 = instr->Bits(7, 5);
1671 if ((opc1 == 0) && (crn == 7)) {
1674 if ((crm == 10) && (opc2 == 5)) {
1675 Format(instr,
"mcr'cond (CP15DMB)");
1676 }
else if ((crm == 10) && (opc2 == 4)) {
1677 Format(instr,
"mcr'cond (CP15DSB)");
1678 }
else if ((crm == 5) && (opc2 == 4)) {
1679 Format(instr,
"mcr'cond (CP15ISB)");
1691 void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(
1692 Instruction* instr) {
1693 VERIFY((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) &&
1694 (instr->VAValue() == 0x0));
1696 bool to_arm_register = (instr->VLValue() == 0x1);
1698 if (to_arm_register) {
1699 Format(instr,
"vmov'cond 'rt, 'Sn");
1701 Format(instr,
"vmov'cond 'Sn, 'rt");
1706 void Decoder::DecodeVCMP(Instruction* instr) {
1707 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
1708 VERIFY(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
1709 (instr->Opc3Value() & 0x1));
1712 bool dp_operation = (instr->SzValue() == 1);
1713 bool raise_exception_for_qnan = (instr->Bit(7) == 0x1);
1715 if (dp_operation && !raise_exception_for_qnan) {
1716 if (instr->Opc2Value() == 0x4) {
1717 Format(instr,
"vcmp'cond.f64 'Dd, 'Dm");
1718 }
else if (instr->Opc2Value() == 0x5) {
1719 Format(instr,
"vcmp'cond.f64 'Dd, #0.0");
1723 }
else if (!raise_exception_for_qnan) {
1724 if (instr->Opc2Value() == 0x4) {
1725 Format(instr,
"vcmp'cond.f32 'Sd, 'Sm");
1726 }
else if (instr->Opc2Value() == 0x5) {
1727 Format(instr,
"vcmp'cond.f32 'Sd, #0.0");
1737 void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
1738 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
1739 VERIFY((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3));
1741 bool double_to_single = (instr->SzValue() == 1);
1743 if (double_to_single) {
1744 Format(instr,
"vcvt'cond.f32.f64 'Sd, 'Dm");
1746 Format(instr,
"vcvt'cond.f64.f32 'Dd, 'Sm");
1751 void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
1752 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
1753 VERIFY(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) ||
1754 (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1)));
1756 bool to_integer = (instr->Bit(18) == 1);
1757 bool dp_operation = (instr->SzValue() == 1);
1759 bool unsigned_integer = (instr->Bit(16) == 0);
1762 if (unsigned_integer) {
1763 Format(instr,
"vcvt'cond.u32.f64 'Sd, 'Dm");
1765 Format(instr,
"vcvt'cond.s32.f64 'Sd, 'Dm");
1768 if (unsigned_integer) {
1769 Format(instr,
"vcvt'cond.u32.f32 'Sd, 'Sm");
1771 Format(instr,
"vcvt'cond.s32.f32 'Sd, 'Sm");
1775 bool unsigned_integer = (instr->Bit(7) == 0);
1778 if (unsigned_integer) {
1779 Format(instr,
"vcvt'cond.f64.u32 'Dd, 'Sm");
1781 Format(instr,
"vcvt'cond.f64.s32 'Dd, 'Sm");
1784 if (unsigned_integer) {
1785 Format(instr,
"vcvt'cond.f32.u32 'Sd, 'Sm");
1787 Format(instr,
"vcvt'cond.f32.s32 'Sd, 'Sm");
1799 void Decoder::DecodeType6CoprocessorIns(Instruction* instr) {
1800 VERIFY(instr->TypeValue() == 6);
1802 if (instr->CoprocessorValue() == 0xA) {
1803 switch (instr->OpcodeValue()) {
1806 if (instr->HasL()) {
1807 Format(instr,
"vldr'cond 'Sd, ['rn - 4*'imm08@00]");
1809 Format(instr,
"vstr'cond 'Sd, ['rn - 4*'imm08@00]");
1814 if (instr->HasL()) {
1815 Format(instr,
"vldr'cond 'Sd, ['rn + 4*'imm08@00]");
1817 Format(instr,
"vstr'cond 'Sd, ['rn + 4*'imm08@00]");
1826 bool to_vfp_register = (instr->VLValue() == 0x1);
1827 if (to_vfp_register) {
1828 Format(instr,
"vldm'cond'pu 'rn'w, {'Sd-'Sd+}");
1830 Format(instr,
"vstm'cond'pu 'rn'w, {'Sd-'Sd+}");
1837 }
else if (instr->CoprocessorValue() == 0xB) {
1838 switch (instr->OpcodeValue()) {
1841 if (instr->Bits(7, 6) != 0 || instr->Bit(4) != 1) {
1843 }
else if (instr->HasL()) {
1844 Format(instr,
"vmov'cond 'rt, 'rn, 'Dm");
1846 Format(instr,
"vmov'cond 'Dm, 'rt, 'rn");
1851 if (instr->HasL()) {
1852 Format(instr,
"vldr'cond 'Dd, ['rn - 4*'imm08@00]");
1854 Format(instr,
"vstr'cond 'Dd, ['rn - 4*'imm08@00]");
1859 if (instr->HasL()) {
1860 Format(instr,
"vldr'cond 'Dd, ['rn + 4*'imm08@00]");
1862 Format(instr,
"vstr'cond 'Dd, ['rn + 4*'imm08@00]");
1871 bool to_vfp_register = (instr->VLValue() == 0x1);
1872 if (to_vfp_register) {
1873 Format(instr,
"vldm'cond'pu 'rn'w, {'Dd-'Dd+}");
1875 Format(instr,
"vstm'cond'pu 'rn'w, {'Dd-'Dd+}");
1888 static const char*
const barrier_option_names[] = {
1889 "invalid",
"oshld",
"oshst",
"osh",
"invalid",
"nshld",
"nshst",
"nsh",
1890 "invalid",
"ishld",
"ishst",
"ish",
"invalid",
"ld",
"st",
"sy",
1894 void Decoder::DecodeSpecialCondition(Instruction* instr) {
1895 switch (instr->SpecialValue()) {
1898 if (instr->Bit(6) == 0) {
1899 Vd = instr->VFPDRegValue(kDoublePrecision);
1900 Vm = instr->VFPMRegValue(kDoublePrecision);
1901 Vn = instr->VFPNRegValue(kDoublePrecision);
1903 Vd = instr->VFPDRegValue(kSimd128Precision);
1904 Vm = instr->VFPMRegValue(kSimd128Precision);
1905 Vn = instr->VFPNRegValue(kSimd128Precision);
1907 int size = kBitsPerByte * (1 << instr->Bits(21, 20));
1908 switch (instr->Bits(11, 8)) {
1910 if (instr->Bit(4) == 1) {
1913 SNPrintF(out_buffer_ + out_buffer_pos_,
1914 "vqadd.s%d q%d, q%d, q%d", size, Vd, Vn, Vm);
1921 if (instr->Bits(21, 20) == 2 && instr->Bit(6) == 1 &&
1922 instr->Bit(4) == 1) {
1925 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1926 "vmov q%d, q%d", Vd, Vm);
1929 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1930 "vorr q%d, q%d, q%d", Vd, Vn, Vm);
1932 }
else if (instr->Bits(21, 20) == 0 && instr->Bit(6) == 1 &&
1933 instr->Bit(4) == 1) {
1935 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1936 "vand q%d, q%d, q%d", Vd, Vn, Vm);
1943 if (instr->Bit(4) == 1) {
1946 SNPrintF(out_buffer_ + out_buffer_pos_,
1947 "vqsub.s%d q%d, q%d, q%d", size, Vd, Vn, Vm);
1954 const char* op = (instr->Bit(4) == 1) ?
"vcge" :
"vcgt";
1957 SNPrintF(out_buffer_ + out_buffer_pos_,
"%s.s%d q%d, q%d, q%d",
1958 op, size, Vd, Vn, Vm);
1963 const char* op = instr->Bit(4) == 1 ?
"vmin" :
"vmax";
1965 SNPrintF(out_buffer_ + out_buffer_pos_,
"%s.s%d q%d, q%d, q%d",
1966 op, size, Vd, Vn, Vm);
1970 const char* op = (instr->Bit(4) == 0) ?
"vadd" :
"vtst";
1973 SNPrintF(out_buffer_ + out_buffer_pos_,
"%s.i%d q%d, q%d, q%d",
1974 op, size, Vd, Vn, Vm);
1978 if (instr->Bit(6) == 1 && instr->Bit(4) == 1) {
1981 SNPrintF(out_buffer_ + out_buffer_pos_,
1982 "vmul.i%d q%d, q%d, q%d", size, Vd, Vn, Vm);
1990 const char* op = instr->Bit(4) == 1 ?
"vpmin" :
"vpmax";
1992 SNPrintF(out_buffer_ + out_buffer_pos_,
"%s.s%d d%d, d%d, d%d",
1993 op, size, Vd, Vn, Vm);
1999 SNPrintF(out_buffer_ + out_buffer_pos_,
"vpadd.i%d d%d, d%d, d%d",
2004 if (instr->Bit(4) == 0) {
2005 const char* op = (instr->Bits(21, 20) == 0) ?
"vadd" :
"vsub";
2007 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2008 "%s.f32 q%d, q%d, q%d", op, Vd, Vn, Vm);
2015 if (instr->Bits(21, 20) == 0 && instr->Bit(4) == 0) {
2017 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2018 "vceq.f32 q%d, q%d, q%d", Vd, Vn, Vm);
2025 if (instr->Bit(20) == 0 && instr->Bit(6) == 1) {
2026 if (instr->Bit(4) == 1) {
2028 const char* op = instr->Bit(21) == 0 ?
"vrecps" :
"vrsqrts";
2030 SNPrintF(out_buffer_ + out_buffer_pos_,
2031 "%s.f32 q%d, q%d, q%d", op, Vd, Vn, Vm);
2034 const char* op = instr->Bit(21) == 1 ?
"vmin" :
"vmax";
2036 SNPrintF(out_buffer_ + out_buffer_pos_,
2037 "%s.f32 q%d, q%d, q%d", op, Vd, Vn, Vm);
2051 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
2052 (instr->Bit(4) == 1)) {
2054 if ((instr->VdValue() & 1) != 0) Unknown(instr);
2055 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1);
2056 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
2057 int imm3 = instr->Bits(21, 19);
2058 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2059 "vmovl.s%d q%d, d%d", imm3 * 8, Vd, Vm);
2060 }
else if (instr->Bits(21, 20) == 3 && instr->Bit(4) == 0) {
2062 int imm4 = instr->Bits(11, 8);
2063 int Vd = instr->VFPDRegValue(kSimd128Precision);
2064 int Vm = instr->VFPMRegValue(kSimd128Precision);
2065 int Vn = instr->VFPNRegValue(kSimd128Precision);
2067 SNPrintF(out_buffer_ + out_buffer_pos_,
"vext.8 q%d, q%d, q%d, #%d",
2069 }
else if (instr->Bits(11, 7) == 0xA && instr->Bit(4) == 1) {
2071 int size = base::bits::RoundDownToPowerOfTwo32(instr->Bits(21, 16));
2072 int shift = instr->Bits(21, 16) - size;
2073 int Vd = instr->VFPDRegValue(kSimd128Precision);
2074 int Vm = instr->VFPMRegValue(kSimd128Precision);
2076 SNPrintF(out_buffer_ + out_buffer_pos_,
"vshl.i%d q%d, q%d, #%d",
2077 size, Vd, Vm, shift);
2078 }
else if (instr->Bits(11, 7) == 0 && instr->Bit(4) == 1) {
2080 int size = base::bits::RoundDownToPowerOfTwo32(instr->Bits(21, 16));
2081 int shift = 2 * size - instr->Bits(21, 16);
2082 int Vd = instr->VFPDRegValue(kSimd128Precision);
2083 int Vm = instr->VFPMRegValue(kSimd128Precision);
2085 SNPrintF(out_buffer_ + out_buffer_pos_,
"vshr.s%d q%d, q%d, #%d",
2086 size, Vd, Vm, shift);
2093 if (instr->Bit(6) == 0) {
2094 Vd = instr->VFPDRegValue(kDoublePrecision);
2095 Vm = instr->VFPMRegValue(kDoublePrecision);
2096 Vn = instr->VFPNRegValue(kDoublePrecision);
2098 Vd = instr->VFPDRegValue(kSimd128Precision);
2099 Vm = instr->VFPMRegValue(kSimd128Precision);
2100 Vn = instr->VFPNRegValue(kSimd128Precision);
2102 int size = kBitsPerByte * (1 << instr->Bits(21, 20));
2103 switch (instr->Bits(11, 8)) {
2105 if (instr->Bit(4) == 1) {
2108 SNPrintF(out_buffer_ + out_buffer_pos_,
2109 "vqadd.u%d q%d, q%d, q%d", size, Vd, Vn, Vm);
2116 if (instr->Bits(21, 20) == 1 && instr->Bit(4) == 1) {
2117 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2118 "vbsl q%d, q%d, q%d", Vd, Vn, Vm);
2119 }
else if (instr->Bits(21, 20) == 0 && instr->Bit(4) == 1) {
2120 if (instr->Bit(6) == 0) {
2122 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2123 "veor d%d, d%d, d%d", Vd, Vn, Vm);
2127 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2128 "veor q%d, q%d, q%d", Vd, Vn, Vm);
2136 if (instr->Bit(4) == 1) {
2139 SNPrintF(out_buffer_ + out_buffer_pos_,
2140 "vqsub.u%d q%d, q%d, q%d", size, Vd, Vn, Vm);
2147 const char* op = (instr->Bit(4) == 1) ?
"vcge" :
"vcgt";
2150 SNPrintF(out_buffer_ + out_buffer_pos_,
"%s.u%d q%d, q%d, q%d",
2151 op, size, Vd, Vn, Vm);
2156 const char* op = instr->Bit(4) == 1 ?
"vmin" :
"vmax";
2158 SNPrintF(out_buffer_ + out_buffer_pos_,
"%s.u%d q%d, q%d, q%d",
2159 op, size, Vd, Vn, Vm);
2163 if (instr->Bit(4) == 0) {
2165 SNPrintF(out_buffer_ + out_buffer_pos_,
2166 "vsub.i%d q%d, q%d, q%d", size, Vd, Vn, Vm);
2169 SNPrintF(out_buffer_ + out_buffer_pos_,
2170 "vceq.i%d q%d, q%d, q%d", size, Vd, Vn, Vm);
2176 const char* op = instr->Bit(4) == 1 ?
"vpmin" :
"vpmax";
2178 SNPrintF(out_buffer_ + out_buffer_pos_,
"%s.u%d d%d, d%d, d%d",
2179 op, size, Vd, Vn, Vm);
2183 if (instr->Bits(21, 20) == 0 && instr->Bit(6) == 1 &&
2184 instr->Bit(4) == 1) {
2186 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2187 "vmul.f32 q%d, q%d, q%d", Vd, Vn, Vm);
2188 }
else if (instr->Bits(21, 20) == 0 && instr->Bit(6) == 0 &&
2189 instr->Bit(4) == 0) {
2191 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2192 "vpadd.f32 d%d, d%d, d%d", Vd, Vn, Vm);
2199 if (instr->Bit(20) == 0 && instr->Bit(4) == 0) {
2200 const char* op = (instr->Bit(21) == 0) ?
"vcge" :
"vcgt";
2202 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2203 "%s.f32 q%d, q%d, q%d", op, Vd, Vn, Vm);
2216 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
2217 (instr->Bit(4) == 1)) {
2219 if ((instr->VdValue() & 1) != 0) Unknown(instr);
2220 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1);
2221 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
2222 int imm3 = instr->Bits(21, 19);
2223 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2224 "vmovl.u%d q%d, d%d", imm3 * 8, Vd, Vm);
2225 }
else if (instr->Opc1Value() == 7 && instr->Bit(4) == 0) {
2226 if (instr->Bits(11, 7) == 0x18) {
2227 int Vm = instr->VFPMRegValue(kDoublePrecision);
2228 int imm4 = instr->Bits(19, 16);
2229 int size = 0, index = 0;
2230 if ((imm4 & 0x1) != 0) {
2233 }
else if ((imm4 & 0x2) != 0) {
2240 if (instr->Bit(6) == 0) {
2241 int Vd = instr->VFPDRegValue(kDoublePrecision);
2243 SNPrintF(out_buffer_ + out_buffer_pos_,
"vdup.%i d%d, d%d[%d]",
2244 size, Vd, Vm, index);
2246 int Vd = instr->VFPDRegValue(kSimd128Precision);
2248 SNPrintF(out_buffer_ + out_buffer_pos_,
"vdup.%i q%d, d%d[%d]",
2249 size, Vd, Vm, index);
2251 }
else if (instr->Bits(11, 10) == 0x2) {
2252 int Vd = instr->VFPDRegValue(kDoublePrecision);
2253 int Vn = instr->VFPNRegValue(kDoublePrecision);
2254 int Vm = instr->VFPMRegValue(kDoublePrecision);
2255 int len = instr->Bits(9, 8);
2256 NeonListOperand list(DwVfpRegister::from_code(Vn), len + 1);
2258 SNPrintF(out_buffer_ + out_buffer_pos_,
"%s d%d, ",
2259 instr->Bit(6) == 0 ?
"vtbl.8" :
"vtbx.8", Vd);
2260 FormatNeonList(Vn, list.type());
2263 }
else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 8) == 0x2 &&
2264 instr->Bits(7, 6) != 0) {
2266 int Vd = instr->VFPDRegValue(kDoublePrecision);
2267 int Vm = instr->VFPMRegValue(kSimd128Precision);
2268 char type = instr->Bit(6) != 0 ?
'u' :
's';
2269 int size = 2 * kBitsPerByte * (1 << instr->Bits(19, 18));
2271 SNPrintF(out_buffer_ + out_buffer_pos_,
"vqmovn.%c%i d%d, q%d",
2272 type, size, Vd, Vm);
2275 if (instr->Bit(6) == 0) {
2276 Vd = instr->VFPDRegValue(kDoublePrecision);
2277 Vm = instr->VFPMRegValue(kDoublePrecision);
2279 Vd = instr->VFPDRegValue(kSimd128Precision);
2280 Vm = instr->VFPMRegValue(kSimd128Precision);
2282 if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 7) == 0) {
2283 if (instr->Bit(6) == 0) {
2284 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2285 "vswp d%d, d%d", Vd, Vm);
2287 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2288 "vswp q%d, q%d", Vd, Vm);
2290 }
else if (instr->Bits(19, 16) == 0 && instr->Bits(11, 6) == 0x17) {
2291 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2292 "vmvn q%d, q%d", Vd, Vm);
2293 }
else if (instr->Bits(19, 16) == 0xB && instr->Bits(11, 9) == 0x3 &&
2294 instr->Bit(6) == 1) {
2295 const char* suffix =
nullptr;
2296 int op = instr->Bits(8, 7);
2311 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2312 "vcvt.%s q%d, q%d", suffix, Vd, Vm);
2313 }
else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 8) == 0x1) {
2314 int size = kBitsPerByte * (1 << instr->Bits(19, 18));
2315 const char* op = instr->Bit(7) != 0 ?
"vzip" :
"vuzp";
2316 if (instr->Bit(6) == 0) {
2318 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2319 "%s.%d d%d, d%d", op, size, Vd, Vm);
2322 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2323 "%s.%d q%d, q%d", op, size, Vd, Vm);
2325 }
else if (instr->Bits(17, 16) == 0 && instr->Bits(11, 9) == 0 &&
2326 instr->Bit(6) == 1) {
2327 int size = kBitsPerByte * (1 << instr->Bits(19, 18));
2328 int op = kBitsPerByte
2329 << (
static_cast<int>(Neon64) - instr->Bits(8, 7));
2331 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2332 "vrev%d.%d q%d, q%d", op, size, Vd, Vm);
2333 }
else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 7) == 0x1) {
2334 int size = kBitsPerByte * (1 << instr->Bits(19, 18));
2335 if (instr->Bit(6) == 0) {
2337 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2338 "vtrn.%d d%d, d%d", size, Vd, Vm);
2341 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2342 "vtrn.%d q%d, q%d", size, Vd, Vm);
2344 }
else if (instr->Bits(17, 16) == 0x1 && instr->Bit(11) == 0 &&
2345 instr->Bit(6) == 1) {
2346 int size = kBitsPerByte * (1 << instr->Bits(19, 18));
2347 char type = instr->Bit(10) != 0 ?
'f' :
's';
2348 if (instr->Bits(9, 6) == 0xD) {
2351 SNPrintF(out_buffer_ + out_buffer_pos_,
"vabs.%c%d q%d, q%d",
2352 type, size, Vd, Vm);
2353 }
else if (instr->Bits(9, 6) == 0xF) {
2356 SNPrintF(out_buffer_ + out_buffer_pos_,
"vneg.%c%d q%d, q%d",
2357 type, size, Vd, Vm);
2361 }
else if (instr->Bits(19, 18) == 0x2 && instr->Bits(11, 8) == 0x5 &&
2362 instr->Bit(6) == 1) {
2364 const char* op = instr->Bit(7) == 0 ?
"vrecpe" :
"vrsqrte";
2365 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2366 "%s.f32 q%d, q%d", op, Vd, Vm);
2371 }
else if (instr->Bits(11, 7) == 0 && instr->Bit(4) == 1 &&
2372 instr->Bit(6) == 1) {
2374 int size = base::bits::RoundDownToPowerOfTwo32(instr->Bits(21, 16));
2375 int shift = 2 * size - instr->Bits(21, 16);
2376 int Vd = instr->VFPDRegValue(kSimd128Precision);
2377 int Vm = instr->VFPMRegValue(kSimd128Precision);
2379 SNPrintF(out_buffer_ + out_buffer_pos_,
"vshr.u%d q%d, q%d, #%d",
2380 size, Vd, Vm, shift);
2381 }
else if (instr->Bit(10) == 1 && instr->Bit(6) == 0 &&
2382 instr->Bit(4) == 1) {
2385 int imm7 = instr->Bits(21, 16);
2386 if (instr->Bit(7) != 0) imm7 += 64;
2387 int size = base::bits::RoundDownToPowerOfTwo32(imm7);
2390 if (instr->Bit(8) == 1) {
2391 shift = imm7 - size;
2394 shift = 2 * size - imm7;
2397 int Vd = instr->VFPDRegValue(kDoublePrecision);
2398 int Vm = instr->VFPMRegValue(kDoublePrecision);
2400 SNPrintF(out_buffer_ + out_buffer_pos_,
"vs%ci.%d d%d, d%d, #%d",
2401 direction, size, Vd, Vm, shift);
2407 if (instr->Bits(21, 20) == 0) {
2409 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
2410 int Rn = instr->VnValue();
2411 int type = instr->Bits(11, 8);
2412 int size = instr->Bits(7, 6);
2413 int align = instr->Bits(5, 4);
2414 int Rm = instr->VmValue();
2415 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"vst1.%d ",
2417 FormatNeonList(Vd, type);
2419 FormatNeonMemory(Rn, align, Rm);
2420 }
else if (instr->Bits(21, 20) == 2) {
2422 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
2423 int Rn = instr->VnValue();
2424 int type = instr->Bits(11, 8);
2425 int size = instr->Bits(7, 6);
2426 int align = instr->Bits(5, 4);
2427 int Rm = instr->VmValue();
2428 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"vld1.%d ",
2430 FormatNeonList(Vd, type);
2432 FormatNeonMemory(Rn, align, Rm);
2439 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xF)) {
2440 const char* rn_name = converter_.NameOfCPURegister(instr->Bits(19, 16));
2441 int offset = instr->Bits(11, 0);
2444 SNPrintF(out_buffer_ + out_buffer_pos_,
"pld [%s]", rn_name);
2445 }
else if (instr->Bit(23) == 0) {
2446 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2447 "pld [%s, #-%d]", rn_name, offset);
2449 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2450 "pld [%s, #+%d]", rn_name, offset);
2452 }
else if (instr->SpecialValue() == 0xA && instr->Bits(22, 20) == 7) {
2453 int option = instr->Bits(3, 0);
2454 switch (instr->Bits(7, 4)) {
2456 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"dsb %s",
2457 barrier_option_names[option]);
2460 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"dmb %s",
2461 barrier_option_names[option]);
2464 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"isb %s",
2465 barrier_option_names[option]);
2475 if (instr->Opc1Value() == 0x7 && instr->Bits(19, 18) == 0x2 &&
2476 instr->Bits(11, 9) == 0x5 && instr->Bits(7, 6) == 0x1 &&
2477 instr->Bit(4) == 0x0) {
2479 bool dp_operation = (instr->SzValue() == 1);
2480 int rounding_mode = instr->Bits(17, 16);
2481 switch (rounding_mode) {
2484 Format(instr,
"vrinta.f64.f64 'Dd, 'Dm");
2486 Format(instr,
"vrinta.f32.f32 'Sd, 'Sm");
2491 Format(instr,
"vrintn.f64.f64 'Dd, 'Dm");
2493 Format(instr,
"vrintn.f32.f32 'Sd, 'Sm");
2498 Format(instr,
"vrintp.f64.f64 'Dd, 'Dm");
2500 Format(instr,
"vrintp.f32.f32 'Sd, 'Sm");
2505 Format(instr,
"vrintm.f64.f64 'Dd, 'Dm");
2507 Format(instr,
"vrintm.f32.f32 'Sd, 'Sm");
2514 }
else if ((instr->Opc1Value() == 0x4) && (instr->Bits(11, 9) == 0x5) &&
2515 (instr->Bit(4) == 0x0)) {
2517 if (instr->SzValue() == 0x1) {
2518 if (instr->Bit(6) == 0x1) {
2519 Format(instr,
"vminnm.f64 'Dd, 'Dn, 'Dm");
2521 Format(instr,
"vmaxnm.f64 'Dd, 'Dn, 'Dm");
2524 if (instr->Bit(6) == 0x1) {
2525 Format(instr,
"vminnm.f32 'Sd, 'Sn, 'Sm");
2527 Format(instr,
"vmaxnm.f32 'Sd, 'Sn, 'Sm");
2535 if ((instr->Bits(11, 9) == 0x5) && (instr->Bit(6) == 0) &&
2536 (instr->Bit(4) == 0)) {
2538 bool dp_operation = (instr->SzValue() == 1);
2539 switch (instr->Bits(21, 20)) {
2542 Format(instr,
"vseleq.f64 'Dd, 'Dn, 'Dm");
2544 Format(instr,
"vseleq.f32 'Sd, 'Sn, 'Sm");
2549 Format(instr,
"vselvs.f64 'Dd, 'Dn, 'Dm");
2551 Format(instr,
"vselvs.f32 'Sd, 'Sn, 'Sm");
2556 Format(instr,
"vselge.f64 'Dd, 'Dn, 'Dm");
2558 Format(instr,
"vselge.f32 'Sd, 'Sn, 'Sm");
2563 Format(instr,
"vselgt.f64 'Dd, 'Dn, 'Dm");
2565 Format(instr,
"vselgt.f32 'Sd, 'Sn, 'Sm");
2584 bool Decoder::IsConstantPoolAt(byte* instr_ptr) {
2585 int instruction_bits = *(
reinterpret_cast<int*
>(instr_ptr));
2586 return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker;
2590 int Decoder::ConstantPoolSizeAt(byte* instr_ptr) {
2591 if (IsConstantPoolAt(instr_ptr)) {
2592 int instruction_bits = *(
reinterpret_cast<int*
>(instr_ptr));
2593 return DecodeConstantPoolLength(instruction_bits);
2601 int Decoder::InstructionDecode(byte* instr_ptr) {
2602 Instruction* instr = Instruction::At(reinterpret_cast<Address>(instr_ptr));
2604 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2606 instr->InstructionBits());
2607 if (instr->ConditionField() == kSpecialCondition) {
2608 DecodeSpecialCondition(instr);
2611 int instruction_bits = *(
reinterpret_cast<int*
>(instr_ptr));
2612 if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) {
2613 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
2614 "constant pool begin (length %d)",
2615 DecodeConstantPoolLength(instruction_bits));
2618 switch (instr->TypeValue()) {
2621 DecodeType01(instr);
2645 return DecodeType7(instr);
2666 const char* NameConverter::NameOfAddress(byte* addr)
const {
2667 v8::internal::SNPrintF(tmp_buffer_,
"%p", static_cast<void*>(addr));
2668 return tmp_buffer_.start();
2672 const char* NameConverter::NameOfConstant(byte* addr)
const {
2673 return NameOfAddress(addr);
2677 const char* NameConverter::NameOfCPURegister(
int reg)
const {
2678 return RegisterName(i::Register::from_code(reg));
2682 const char* NameConverter::NameOfByteCPURegister(
int reg)
const {
2688 const char* NameConverter::NameOfXMMRegister(
int reg)
const {
2694 const char* NameConverter::NameInCode(byte* addr)
const {
2704 byte* instruction) {
2706 return d.InstructionDecode(instruction);
2710 int Disassembler::ConstantPoolSizeAt(byte* instruction) {
2711 return v8::internal::Decoder::ConstantPoolSizeAt(instruction);
2714 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end,
2715 UnimplementedOpcodeAction unimplemented_action) {
2716 NameConverter converter;
2717 Disassembler d(converter, unimplemented_action);
2718 for (byte* pc = begin; pc < end;) {
2722 pc += d.InstructionDecode(buffer, pc);
2723 v8::internal::PrintF(f,
"%p %08x %s\n", static_cast<void*>(prev_pc),
2724 *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
2730 #endif // V8_TARGET_ARCH_ARM