12 #if V8_TARGET_ARCH_ARM64
52 void Disassembler::VisitAddSubImmediate(Instruction* instr) {
54 bool stack_op = (rd_is_zr ||
RnIsZROrSP(instr)) &&
55 (instr->ImmAddSub() == 0) ?
true :
false;
56 const char *mnemonic =
"";
57 const char *form =
"'Rds, 'Rns, 'IAddSub";
58 const char *form_cmp =
"'Rns, 'IAddSub";
59 const char *form_mov =
"'Rds, 'Rns";
81 case SUB_x_imm: mnemonic =
"sub";
break;
93 Format(instr, mnemonic, form);
97 void Disassembler::VisitAddSubShifted(Instruction* instr) {
100 const char *mnemonic =
"";
101 const char *form =
"'Rd, 'Rn, 'Rm'HDP";
102 const char *form_cmp =
"'Rn, 'Rm'HDP";
103 const char *form_neg =
"'Rd, 'Rm'HDP";
107 case ADD_x_shift: mnemonic =
"add";
break;
132 }
else if (rn_is_zr) {
140 Format(instr, mnemonic, form);
144 void Disassembler::VisitAddSubExtended(Instruction* instr) {
146 const char *mnemonic =
"";
149 "'Rds, 'Rns, 'Xm'Ext" :
"'Rds, 'Rns, 'Wm'Ext";
151 "'Rns, 'Xm'Ext" :
"'Rns, 'Wm'Ext";
155 case ADD_x_ext: mnemonic =
"add";
break;
166 case SUB_x_ext: mnemonic =
"sub";
break;
178 Format(instr, mnemonic, form);
182 void Disassembler::VisitAddSubWithCarry(Instruction* instr) {
184 const char *mnemonic =
"";
185 const char *form =
"'Rd, 'Rn, 'Rm";
186 const char *form_neg =
"'Rd, 'Rm";
190 case ADC_x: mnemonic =
"adc";
break;
192 case ADCS_x: mnemonic =
"adcs";
break;
213 Format(instr, mnemonic, form);
217 void Disassembler::VisitLogicalImmediate(Instruction* instr) {
220 const char *mnemonic =
"";
221 const char *form =
"'Rds, 'Rn, 'ITri";
223 if (instr->ImmLogical() == 0) {
225 Format(instr,
"unallocated",
"(LogicalImmediate)");
237 if (rn_is_zr && !
IsMovzMovnImm(reg_size, instr->ImmLogical())) {
239 form =
"'Rds, 'ITri";
256 Format(instr, mnemonic, form);
265 if (((value & 0xffffffffffff0000UL) == 0UL) ||
266 ((value & 0xffffffff0000ffffUL) == 0UL) ||
267 ((value & 0xffff0000ffffffffUL) == 0UL) ||
268 ((value & 0x0000ffffffffffffUL) == 0UL)) {
274 (((value & 0xffffffffffff0000UL) == 0xffffffffffff0000UL) ||
275 ((value & 0xffffffff0000ffffUL) == 0xffffffff0000ffffUL) ||
276 ((value & 0xffff0000ffffffffUL) == 0xffff0000ffffffffUL) ||
277 ((value & 0x0000ffffffffffffUL) == 0x0000ffffffffffffUL))) {
281 (((value & 0xffff0000) == 0xffff0000) ||
282 ((value & 0x0000ffff) == 0x0000ffff))) {
289 void Disassembler::VisitLogicalShifted(Instruction* instr) {
292 const char *mnemonic =
"";
293 const char *form =
"'Rd, 'Rn, 'Rm'HLo";
297 case AND_x: mnemonic =
"and";
break;
299 case BIC_x: mnemonic =
"bic";
break;
301 case EOR_x: mnemonic =
"eor";
break;
303 case EON_x: mnemonic =
"eon";
break;
305 case BICS_x: mnemonic =
"bics";
break;
311 form =
"'Rn, 'Rm'HLo";
318 if (rn_is_zr && (instr->ImmDPShift() == 0) && (instr->ShiftDP() ==
LSL)) {
329 form =
"'Rd, 'Rm'HLo";
336 Format(instr, mnemonic, form);
340 void Disassembler::VisitConditionalCompareRegister(Instruction* instr) {
341 const char *mnemonic =
"";
342 const char *form =
"'Rn, 'Rm, 'INzcv, 'Cond";
346 case CCMN_x: mnemonic =
"ccmn";
break;
348 case CCMP_x: mnemonic =
"ccmp";
break;
351 Format(instr, mnemonic, form);
355 void Disassembler::VisitConditionalCompareImmediate(Instruction* instr) {
356 const char *mnemonic =
"";
357 const char *form =
"'Rn, 'IP, 'INzcv, 'Cond";
366 Format(instr, mnemonic, form);
370 void Disassembler::VisitConditionalSelect(Instruction* instr) {
372 bool rn_is_rm = (instr->Rn() == instr->Rm());
373 const char *mnemonic =
"";
374 const char *form =
"'Rd, 'Rn, 'Rm, 'Cond";
375 const char *form_test =
"'Rd, 'CInv";
376 const char *form_update =
"'Rd, 'Rn, 'CInv";
379 bool invertible_cond = (cond !=
al) && (cond !=
nv);
383 case CSEL_x: mnemonic =
"csel";
break;
387 if (rnm_is_zr && invertible_cond) {
390 }
else if (rn_is_rm && invertible_cond) {
399 if (rnm_is_zr && invertible_cond) {
402 }
else if (rn_is_rm && invertible_cond) {
411 if (rn_is_rm && invertible_cond) {
419 Format(instr, mnemonic, form);
423 void Disassembler::VisitBitfield(Instruction* instr) {
424 unsigned s = instr->ImmS();
425 unsigned r = instr->ImmR();
426 unsigned rd_size_minus_1 =
428 const char *mnemonic =
"";
429 const char *form =
"";
430 const char *form_shift_right =
"'Rd, 'Rn, 'IBr";
431 const char *form_extend =
"'Rd, 'Wn";
432 const char *form_bfiz =
"'Rd, 'Rn, 'IBZ-r, 'IBs+1";
433 const char *form_bfx =
"'Rd, 'Rn, 'IBr, 'IBs-r+1";
434 const char *form_lsl =
"'Rd, 'Rn, 'IBZ-r";
445 }
else if (s == 15) {
447 }
else if ((s == 31) && (instr->SixtyFourBits() == 1)) {
452 }
else if (s == rd_size_minus_1) {
454 form = form_shift_right;
469 }
else if (s == 15) {
475 if (s == rd_size_minus_1) {
477 form = form_shift_right;
478 }
else if (r == s + 1) {
497 Format(instr, mnemonic, form);
501 void Disassembler::VisitExtract(Instruction* instr) {
502 const char *mnemonic =
"";
503 const char *form =
"'Rd, 'Rn, 'Rm, 'IExtract";
508 if (instr->Rn() == instr->Rm()) {
510 form =
"'Rd, 'Rn, 'IExtract";
518 Format(instr, mnemonic, form);
522 void Disassembler::VisitPCRelAddressing(Instruction* instr) {
524 case ADR:
Format(instr,
"adr",
"'Xd, 'AddrPCRelByte");
break;
526 default:
Format(instr,
"unimplemented",
"(PCRelAddressing)");
531 void Disassembler::VisitConditionalBranch(Instruction* instr) {
533 case B_cond:
Format(instr,
"b.'CBrn",
"'BImmCond");
break;
539 void Disassembler::VisitUnconditionalBranchToRegister(Instruction* instr) {
540 const char *mnemonic =
"unimplemented";
541 const char *form =
"'Xn";
544 case BR: mnemonic =
"br";
break;
545 case BLR: mnemonic =
"blr";
break;
553 default: form =
"(UnconditionalBranchToRegister)";
555 Format(instr, mnemonic, form);
559 void Disassembler::VisitUnconditionalBranch(Instruction* instr) {
560 const char *mnemonic =
"";
561 const char *form =
"'BImmUncn";
564 case B: mnemonic =
"b";
break;
565 case BL: mnemonic =
"bl";
break;
568 Format(instr, mnemonic, form);
572 void Disassembler::VisitDataProcessing1Source(Instruction* instr) {
573 const char *mnemonic =
"";
574 const char *form =
"'Rd, 'Rn";
577 #define FORMAT(A, B) \
579 case A##_x: mnemonic = B; break;
580 FORMAT(
RBIT,
"rbit");
581 FORMAT(
REV16,
"rev16");
586 case REV32_x: mnemonic =
"rev32";
break;
589 Format(instr, mnemonic, form);
593 void Disassembler::VisitDataProcessing2Source(Instruction* instr) {
594 const char *mnemonic =
"unimplemented";
595 const char *form =
"'Rd, 'Rn, 'Rm";
598 #define FORMAT(A, B) \
600 case A##_x: mnemonic = B; break;
601 FORMAT(
UDIV,
"udiv");
602 FORMAT(
SDIV,
"sdiv");
608 default: form =
"(DataProcessing2Source)";
610 Format(instr, mnemonic, form);
614 void Disassembler::VisitDataProcessing3Source(Instruction* instr) {
616 const char *mnemonic =
"";
617 const char *form =
"'Xd, 'Wn, 'Wm, 'Xa";
618 const char *form_rrr =
"'Rd, 'Rn, 'Rm";
619 const char *form_rrrr =
"'Rd, 'Rn, 'Rm, 'Ra";
620 const char *form_xww =
"'Xd, 'Wn, 'Wm";
621 const char *form_xxx =
"'Xd, 'Xn, 'Xm";
688 Format(instr, mnemonic, form);
692 void Disassembler::VisitCompareBranch(Instruction* instr) {
693 const char *mnemonic =
"";
694 const char *form =
"'Rt, 'BImmCmpa";
698 case CBZ_x: mnemonic =
"cbz";
break;
700 case CBNZ_x: mnemonic =
"cbnz";
break;
703 Format(instr, mnemonic, form);
707 void Disassembler::VisitTestBranch(Instruction* instr) {
708 const char *mnemonic =
"";
713 const char *form =
"'Rt, 'IS, 'BImmTest";
716 case TBZ: mnemonic =
"tbz";
break;
717 case TBNZ: mnemonic =
"tbnz";
break;
720 Format(instr, mnemonic, form);
724 void Disassembler::VisitMoveWideImmediate(Instruction* instr) {
725 const char *mnemonic =
"";
726 const char *form =
"'Rd, 'IMoveImm";
733 case MOVN_x: mnemonic =
"movn";
break;
735 case MOVZ_x: mnemonic =
"movz";
break;
737 case MOVK_x: mnemonic =
"movk"; form =
"'Rd, 'IMoveLSL";
break;
740 Format(instr, mnemonic, form);
744 #define LOAD_STORE_LIST(V) \
745 V(STRB_w, "strb", "'Wt") \
746 V(STRH_w, "strh", "'Wt") \
747 V(STR_w, "str", "'Wt") \
748 V(STR_x, "str", "'Xt") \
749 V(LDRB_w, "ldrb", "'Wt") \
750 V(LDRH_w, "ldrh", "'Wt") \
751 V(LDR_w, "ldr", "'Wt") \
752 V(LDR_x, "ldr", "'Xt") \
753 V(LDRSB_x, "ldrsb", "'Xt") \
754 V(LDRSH_x, "ldrsh", "'Xt") \
755 V(LDRSW_x, "ldrsw", "'Xt") \
756 V(LDRSB_w, "ldrsb", "'Wt") \
757 V(LDRSH_w, "ldrsh", "'Wt") \
758 V(STR_s, "str", "'St") \
759 V(STR_d, "str", "'Dt") \
760 V(LDR_s, "ldr", "'St") \
761 V(LDR_d, "ldr", "'Dt")
763 void Disassembler::VisitLoadStorePreIndex(Instruction* instr) {
764 const char *mnemonic =
"unimplemented";
765 const char *form =
"(LoadStorePreIndex)";
768 #define LS_PREINDEX(A, B, C) \
769 case A##_pre: mnemonic = B; form = C ", ['Xns'ILS]!"; break;
770 LOAD_STORE_LIST(LS_PREINDEX)
773 Format(instr, mnemonic, form);
777 void Disassembler::VisitLoadStorePostIndex(Instruction* instr) {
778 const char *mnemonic =
"unimplemented";
779 const char *form =
"(LoadStorePostIndex)";
782 #define LS_POSTINDEX(A, B, C) \
783 case A##_post: mnemonic = B; form = C ", ['Xns]'ILS"; break;
784 LOAD_STORE_LIST(LS_POSTINDEX)
787 Format(instr, mnemonic, form);
791 void Disassembler::VisitLoadStoreUnsignedOffset(Instruction* instr) {
792 const char *mnemonic =
"unimplemented";
793 const char *form =
"(LoadStoreUnsignedOffset)";
796 #define LS_UNSIGNEDOFFSET(A, B, C) \
797 case A##_unsigned: mnemonic = B; form = C ", ['Xns'ILU]"; break;
798 LOAD_STORE_LIST(LS_UNSIGNEDOFFSET)
799 #undef LS_UNSIGNEDOFFSET
800 case PRFM_unsigned: mnemonic =
"prfm"; form =
"'PrefOp, ['Xn'ILU]";
802 Format(instr, mnemonic, form);
806 void Disassembler::VisitLoadStoreRegisterOffset(Instruction* instr) {
807 const char *mnemonic =
"unimplemented";
808 const char *form =
"(LoadStoreRegisterOffset)";
811 #define LS_REGISTEROFFSET(A, B, C) \
812 case A##_reg: mnemonic = B; form = C ", ['Xns, 'Offsetreg]"; break;
813 LOAD_STORE_LIST(LS_REGISTEROFFSET)
814 #undef LS_REGISTEROFFSET
815 case PRFM_reg: mnemonic =
"prfm"; form =
"'PrefOp, ['Xns, 'Offsetreg]";
817 Format(instr, mnemonic, form);
821 void Disassembler::VisitLoadStoreUnscaledOffset(Instruction* instr) {
822 const char *mnemonic =
"unimplemented";
823 const char *form =
"'Wt, ['Xns'ILS]";
824 const char *form_x =
"'Xt, ['Xns'ILS]";
825 const char *form_s =
"'St, ['Xns'ILS]";
826 const char *form_d =
"'Dt, ['Xns'ILS]";
829 case STURB_w: mnemonic =
"sturb";
break;
830 case STURH_w: mnemonic =
"sturh";
break;
831 case STUR_w: mnemonic =
"stur";
break;
832 case STUR_x: mnemonic =
"stur"; form = form_x;
break;
833 case STUR_s: mnemonic =
"stur"; form = form_s;
break;
834 case STUR_d: mnemonic =
"stur"; form = form_d;
break;
835 case LDURB_w: mnemonic =
"ldurb";
break;
836 case LDURH_w: mnemonic =
"ldurh";
break;
837 case LDUR_w: mnemonic =
"ldur";
break;
838 case LDUR_x: mnemonic =
"ldur"; form = form_x;
break;
839 case LDUR_s: mnemonic =
"ldur"; form = form_s;
break;
840 case LDUR_d: mnemonic =
"ldur"; form = form_d;
break;
841 case LDURSB_x: form = form_x;
842 case LDURSB_w: mnemonic =
"ldursb";
break;
843 case LDURSH_x: form = form_x;
844 case LDURSH_w: mnemonic =
"ldursh";
break;
845 case LDURSW_x: mnemonic =
"ldursw"; form = form_x;
break;
846 default: form =
"(LoadStoreUnscaledOffset)";
848 Format(instr, mnemonic, form);
852 void Disassembler::VisitLoadLiteral(Instruction* instr) {
853 const char *mnemonic =
"ldr";
854 const char *form =
"(LoadLiteral)";
857 case LDR_w_lit: form =
"'Wt, 'ILLiteral 'LValue";
break;
858 case LDR_x_lit: form =
"'Xt, 'ILLiteral 'LValue";
break;
859 case LDR_s_lit: form =
"'St, 'ILLiteral 'LValue";
break;
860 case LDR_d_lit: form =
"'Dt, 'ILLiteral 'LValue";
break;
861 default: mnemonic =
"unimplemented";
863 Format(instr, mnemonic, form);
867 #define LOAD_STORE_PAIR_LIST(V) \
868 V(STP_w, "stp", "'Wt, 'Wt2", "4") \
869 V(LDP_w, "ldp", "'Wt, 'Wt2", "4") \
870 V(LDPSW_x, "ldpsw", "'Xt, 'Xt2", "4") \
871 V(STP_x, "stp", "'Xt, 'Xt2", "8") \
872 V(LDP_x, "ldp", "'Xt, 'Xt2", "8") \
873 V(STP_s, "stp", "'St, 'St2", "4") \
874 V(LDP_s, "ldp", "'St, 'St2", "4") \
875 V(STP_d, "stp", "'Dt, 'Dt2", "8") \
876 V(LDP_d, "ldp", "'Dt, 'Dt2", "8")
878 void Disassembler::VisitLoadStorePairPostIndex(Instruction* instr) {
879 const char *mnemonic =
"unimplemented";
880 const char *form =
"(LoadStorePairPostIndex)";
883 #define LSP_POSTINDEX(A, B, C, D) \
884 case A##_post: mnemonic = B; form = C ", ['Xns]'ILP" D; break;
885 LOAD_STORE_PAIR_LIST(LSP_POSTINDEX)
888 Format(instr, mnemonic, form);
892 void Disassembler::VisitLoadStorePairPreIndex(Instruction* instr) {
893 const char *mnemonic =
"unimplemented";
894 const char *form =
"(LoadStorePairPreIndex)";
897 #define LSP_PREINDEX(A, B, C, D) \
898 case A##_pre: mnemonic = B; form = C ", ['Xns'ILP" D "]!"; break;
899 LOAD_STORE_PAIR_LIST(LSP_PREINDEX)
902 Format(instr, mnemonic, form);
906 void Disassembler::VisitLoadStorePairOffset(Instruction* instr) {
907 const char *mnemonic =
"unimplemented";
908 const char *form =
"(LoadStorePairOffset)";
911 #define LSP_OFFSET(A, B, C, D) \
912 case A##_off: mnemonic = B; form = C ", ['Xns'ILP" D "]"; break;
913 LOAD_STORE_PAIR_LIST(LSP_OFFSET)
916 Format(instr, mnemonic, form);
920 void Disassembler::VisitLoadStorePairNonTemporal(Instruction* instr) {
921 const char *mnemonic =
"unimplemented";
925 case STNP_w: mnemonic =
"stnp"; form =
"'Wt, 'Wt2, ['Xns'ILP4]";
break;
926 case LDNP_w: mnemonic =
"ldnp"; form =
"'Wt, 'Wt2, ['Xns'ILP4]";
break;
927 case STNP_x: mnemonic =
"stnp"; form =
"'Xt, 'Xt2, ['Xns'ILP8]";
break;
928 case LDNP_x: mnemonic =
"ldnp"; form =
"'Xt, 'Xt2, ['Xns'ILP8]";
break;
929 case STNP_s: mnemonic =
"stnp"; form =
"'St, 'St2, ['Xns'ILP4]";
break;
930 case LDNP_s: mnemonic =
"ldnp"; form =
"'St, 'St2, ['Xns'ILP4]";
break;
931 case STNP_d: mnemonic =
"stnp"; form =
"'Dt, 'Dt2, ['Xns'ILP8]";
break;
932 case LDNP_d: mnemonic =
"ldnp"; form =
"'Dt, 'Dt2, ['Xns'ILP8]";
break;
933 default: form =
"(LoadStorePairNonTemporal)";
935 Format(instr, mnemonic, form);
939 void Disassembler::VisitFPCompare(Instruction* instr) {
940 const char *mnemonic =
"unimplemented";
941 const char *form =
"'Fn, 'Fm";
942 const char *form_zero =
"'Fn, #0.0";
948 case FCMP_d: mnemonic =
"fcmp";
break;
949 default: form =
"(FPCompare)";
951 Format(instr, mnemonic, form);
955 void Disassembler::VisitFPConditionalCompare(Instruction* instr) {
956 const char *mnemonic =
"unimplemented";
957 const char *form =
"'Fn, 'Fm, 'INzcv, 'Cond";
961 case FCCMP_d: mnemonic =
"fccmp";
break;
963 case FCCMPE_d: mnemonic =
"fccmpe";
break;
964 default: form =
"(FPConditionalCompare)";
966 Format(instr, mnemonic, form);
970 void Disassembler::VisitFPConditionalSelect(Instruction* instr) {
971 const char *mnemonic =
"";
972 const char *form =
"'Fd, 'Fn, 'Fm, 'Cond";
976 case FCSEL_d: mnemonic =
"fcsel";
break;
979 Format(instr, mnemonic, form);
983 void Disassembler::VisitFPDataProcessing1Source(Instruction* instr) {
984 const char *mnemonic =
"unimplemented";
985 const char *form =
"'Fd, 'Fn";
988 #define FORMAT(A, B) \
990 case A##_d: mnemonic = B; break;
991 FORMAT(
FMOV,
"fmov");
992 FORMAT(
FABS,
"fabs");
993 FORMAT(
FNEG,
"fneg");
994 FORMAT(
FSQRT,
"fsqrt");
1000 FORMAT(
FRINTX,
"frintx");
1001 FORMAT(
FRINTI,
"frinti");
1003 case FCVT_ds: mnemonic =
"fcvt"; form =
"'Dd, 'Sn";
break;
1004 case FCVT_sd: mnemonic =
"fcvt"; form =
"'Sd, 'Dn";
break;
1005 default: form =
"(FPDataProcessing1Source)";
1007 Format(instr, mnemonic, form);
1011 void Disassembler::VisitFPDataProcessing2Source(Instruction* instr) {
1012 const char *mnemonic =
"";
1013 const char *form =
"'Fd, 'Fn, 'Fm";
1016 #define FORMAT(A, B) \
1018 case A##_d: mnemonic = B; break;
1019 FORMAT(
FMUL,
"fmul");
1020 FORMAT(
FDIV,
"fdiv");
1021 FORMAT(
FADD,
"fadd");
1022 FORMAT(
FSUB,
"fsub");
1023 FORMAT(
FMAX,
"fmax");
1024 FORMAT(
FMIN,
"fmin");
1025 FORMAT(
FMAXNM,
"fmaxnm");
1026 FORMAT(
FMINNM,
"fminnm");
1027 FORMAT(
FNMUL,
"fnmul");
1031 Format(instr, mnemonic, form);
1035 void Disassembler::VisitFPDataProcessing3Source(Instruction* instr) {
1036 const char *mnemonic =
"";
1037 const char *form =
"'Fd, 'Fn, 'Fm, 'Fa";
1040 #define FORMAT(A, B) \
1042 case A##_d: mnemonic = B; break;
1043 FORMAT(FMADD,
"fmadd");
1044 FORMAT(FMSUB,
"fmsub");
1045 FORMAT(FNMADD,
"fnmadd");
1046 FORMAT(FNMSUB,
"fnmsub");
1050 Format(instr, mnemonic, form);
1054 void Disassembler::VisitFPImmediate(Instruction* instr) {
1055 const char *mnemonic =
"";
1056 const char *form =
"(FPImmediate)";
1059 case FMOV_s_imm: mnemonic =
"fmov"; form =
"'Sd, 'IFPSingle";
break;
1060 case FMOV_d_imm: mnemonic =
"fmov"; form =
"'Dd, 'IFPDouble";
break;
1063 Format(instr, mnemonic, form);
1067 void Disassembler::VisitFPIntegerConvert(Instruction* instr) {
1068 const char *mnemonic =
"unimplemented";
1069 const char *form =
"(FPIntegerConvert)";
1070 const char *form_rf =
"'Rd, 'Fn";
1071 const char *form_fr =
"'Fd, 'Rn";
1075 case FMOV_xd: mnemonic =
"fmov"; form = form_rf;
break;
1077 case FMOV_dx: mnemonic =
"fmov"; form = form_fr;
break;
1081 case FCVTAS_xd: mnemonic =
"fcvtas"; form = form_rf;
break;
1085 case FCVTAU_xd: mnemonic =
"fcvtau"; form = form_rf;
break;
1089 case FCVTMS_xd: mnemonic =
"fcvtms"; form = form_rf;
break;
1093 case FCVTMU_xd: mnemonic =
"fcvtmu"; form = form_rf;
break;
1097 case FCVTNS_xd: mnemonic =
"fcvtns"; form = form_rf;
break;
1101 case FCVTNU_xd: mnemonic =
"fcvtnu"; form = form_rf;
break;
1105 case FCVTZU_xs: mnemonic =
"fcvtzu"; form = form_rf;
break;
1109 case FCVTZS_ws: mnemonic =
"fcvtzs"; form = form_rf;
break;
1113 case SCVTF_dx: mnemonic =
"scvtf"; form = form_fr;
break;
1117 case UCVTF_dx: mnemonic =
"ucvtf"; form = form_fr;
break;
1119 Format(instr, mnemonic, form);
1123 void Disassembler::VisitFPFixedPointConvert(Instruction* instr) {
1124 const char *mnemonic =
"";
1125 const char *form =
"'Rd, 'Fn, 'IFPFBits";
1126 const char *form_fr =
"'Fd, 'Rn, 'IFPFBits";
1146 Format(instr, mnemonic, form);
1150 void Disassembler::VisitSystem(Instruction* instr) {
1154 const char *mnemonic =
"unimplemented";
1155 const char *form =
"(System)";
1161 switch (instr->ImmSystemRegister()) {
1162 case NZCV: form =
"'Xt, nzcv";
break;
1163 case FPCR: form =
"'Xt, fpcr";
break;
1164 default: form =
"'Xt, (unknown)";
break;
1170 switch (instr->ImmSystemRegister()) {
1171 case NZCV: form =
"nzcv, 'Xt";
break;
1172 case FPCR: form =
"fpcr, 'Xt";
break;
1173 default: form =
"(unknown), 'Xt";
break;
1180 switch (instr->ImmHint()) {
1207 Format(instr, mnemonic, form);
1211 void Disassembler::VisitException(Instruction* instr) {
1212 const char *mnemonic =
"unimplemented";
1213 const char *form =
"'IDebug";
1216 case HLT: mnemonic =
"hlt";
break;
1217 case BRK: mnemonic =
"brk";
break;
1218 case SVC: mnemonic =
"svc";
break;
1219 case HVC: mnemonic =
"hvc";
break;
1220 case SMC: mnemonic =
"smc";
break;
1221 case DCPS1: mnemonic =
"dcps1"; form =
"{'IDebug}";
break;
1222 case DCPS2: mnemonic =
"dcps2"; form =
"{'IDebug}";
break;
1223 case DCPS3: mnemonic =
"dcps3"; form =
"{'IDebug}";
break;
1224 default: form =
"(Exception)";
1226 Format(instr, mnemonic, form);
1230 void Disassembler::VisitUnimplemented(Instruction* instr) {
1231 Format(instr,
"unimplemented",
"(Unimplemented)");
1235 void Disassembler::VisitUnallocated(Instruction* instr) {
1236 Format(instr,
"unallocated",
"(Unallocated)");
1246 const char* format) {
1252 if (format !=
NULL) {
1262 char chr = *
string++;
1263 while (chr !=
'\0') {
1275 switch (format[0]) {
1301 const char* format) {
1302 unsigned reg_num = 0;
1303 unsigned field_len = 2;
1304 switch (format[1]) {
1305 case 'd': reg_num = instr->Rd();
break;
1306 case 'n': reg_num = instr->Rn();
break;
1307 case 'm': reg_num = instr->Rm();
break;
1308 case 'a': reg_num = instr->Ra();
break;
1310 if (format[2] ==
'2') {
1311 reg_num = instr->Rt2();
1314 reg_num = instr->Rt();
1322 if (format[2] ==
's') {
1327 if (format[0] ==
'R') {
1329 reg_type = instr->SixtyFourBits() ?
'x' :
'w';
1330 }
else if (format[0] ==
'F') {
1332 reg_type = ((instr->FPType() & 1) == 0) ?
's' :
'd';
1335 reg_type = format[0] + 0x20;
1338 if ((reg_num !=
kZeroRegCode) || (reg_type ==
's') || (reg_type ==
'd')) {
1342 if ((reg_type ==
'x') && (reg_num == 27)) {
1344 }
else if ((reg_type ==
'x') && (reg_num == 28)) {
1346 }
else if ((reg_type ==
'x') && (reg_num == 29)) {
1348 }
else if ((reg_type ==
'x') && (reg_num == 30)) {
1353 }
else if (format[2] ==
's') {
1366 const char* format) {
1367 DCHECK(format[0] ==
'I');
1369 switch (format[1]) {
1371 if (format[5] ==
'I') {
1372 uint64_t imm = instr->ImmMoveWide() << (16 * instr->ShiftMoveWide());
1375 DCHECK(format[5] ==
'L');
1377 if (instr->ShiftMoveWide() > 0) {
1384 switch (format[2]) {
1391 if (instr->ImmLS() != 0) {
1397 if (instr->ImmLSPair() != 0) {
1399 int scale = format[3] - 0x30;
1405 if (instr->ImmLSUnsigned() != 0) {
1407 instr->ImmLSUnsigned() << instr->SizeLS());
1414 int64_t offset = instr->ImmCondBranch() << 2;
1415 char sign = (offset >= 0) ?
'+' :
'-';
1420 DCHECK(instr->ShiftAddSub() <= 1);
1421 int64_t imm = instr->ImmAddSub() << (12 * instr->ShiftAddSub());
1426 if (format[3] ==
'F') {
1431 format[3] ==
'S' ? instr->ImmFP32() : instr->ImmFP64());
1440 int nzcv = (instr->Nzcv() << Flags_offset);
1442 ((nzcv &
ZFlag) == 0) ?
'z' :
'Z',
1443 ((nzcv &
CFlag) == 0) ?
'c' :
'C',
1444 ((nzcv &
VFlag) == 0) ?
'v' :
'V');
1460 instr->ImmTestBranchBit40());
1476 const char* format) {
1477 DCHECK((format[0] ==
'I') && (format[1] ==
'B'));
1478 unsigned r = instr->ImmR();
1479 unsigned s = instr->ImmS();
1481 switch (format[2]) {
1487 if (format[3] ==
'+') {
1491 DCHECK(format[3] ==
'-');
1497 DCHECK((format[3] ==
'-') && (format[4] ==
'r'));
1512 const char* format) {
1513 DCHECK(strncmp(format,
"LValue", 6) == 0);
1521 AppendToOutput(
"(addr 0x%016" PRIxPTR
")", instr->LiteralAddress());
1531 DCHECK(format[0] ==
'H');
1532 DCHECK(instr->ShiftDP() <= 0x3);
1534 switch (format[1]) {
1539 if (instr->ImmDPShift() != 0) {
1540 const char* shift_type[] = {
"lsl",
"lsr",
"asr",
"ror"};
1542 instr->ImmDPShift());
1554 const char* format) {
1555 DCHECK(format[0] ==
'C');
1556 const char* condition_code[] = {
"eq",
"ne",
"hs",
"lo",
1557 "mi",
"pl",
"vs",
"vc",
1558 "hi",
"ls",
"ge",
"lt",
1559 "gt",
"le",
"al",
"nv" };
1561 switch (format[1]) {
1562 case 'B': cond = instr->ConditionBranch();
break;
1567 default: cond = instr->Condition();
1575 const char* format) {
1577 DCHECK(strncmp(format,
"AddrPCRel", 9) == 0);
1579 int offset = instr->ImmPCRel();
1582 DCHECK(strcmp(format,
"AddrPCRelByte") == 0);
1596 const char* format) {
1597 DCHECK(strncmp(format,
"BImm", 4) == 0);
1600 switch (format[5]) {
1602 case 'n': offset = instr->ImmUncondBranch();
break;
1604 case 'o': offset = instr->ImmCondBranch();
break;
1606 case 'm': offset = instr->ImmCmpBranch();
break;
1608 case 'e': offset = instr->ImmTestBranch();
break;
1623 const char* format) {
1624 DCHECK(strncmp(format,
"Ext", 3) == 0);
1625 DCHECK(instr->ExtendMode() <= 7);
1628 const char* extend_mode[] = {
"uxtb",
"uxth",
"uxtw",
"uxtx",
1629 "sxtb",
"sxth",
"sxtw",
"sxtx" };
1634 (((instr->ExtendMode() ==
UXTW) && (instr->SixtyFourBits() == 0)) ||
1635 (instr->ExtendMode() ==
UXTX))) {
1636 if (instr->ImmExtendShift() > 0) {
1641 if (instr->ImmExtendShift() > 0) {
1650 const char* format) {
1651 DCHECK(strncmp(format,
"Offsetreg", 9) == 0);
1652 const char* extend_mode[] = {
"undefined",
"undefined",
"uxtw",
"lsl",
1653 "undefined",
"undefined",
"sxtw",
"sxtx" };
1656 unsigned shift = instr->ImmShiftLS();
1658 char reg_type = ((ext ==
UXTW) || (ext ==
SXTW)) ?
'w' :
'x';
1660 unsigned rm = instr->Rm();
1679 const char* format) {
1680 DCHECK(format[0] ==
'P');
1683 int prefetch_mode = instr->PrefetchMode();
1685 const char*
ls = (prefetch_mode & 0x10) ?
"st" :
"ld";
1686 int level = (prefetch_mode >> 1) + 1;
1687 const char* ks = (prefetch_mode & 1) ?
"strm" :
"keep";
1694 const char* format) {
1695 DCHECK(format[0] ==
'M');
1698 static const char* options[4][4] = {
1699 {
"sy (0b0000)",
"oshld",
"oshst",
"osh" },
1700 {
"sy (0b0100)",
"nshld",
"nshst",
"nsh" },
1701 {
"sy (0b1000)",
"ishld",
"ishst",
"ish" },
1702 {
"sy (0b1100)",
"ld",
"st",
"sy" }
1704 int domain = instr->ImmBarrierDomain();
1705 int type = instr->ImmBarrierType();
1720 va_start(args, format);
1727 fprintf(
stream_,
"0x%016" PRIx64
" %08" PRIx32
"\t\t%s\n",
1728 reinterpret_cast<uint64_t
>(instr), instr->InstructionBits(),
1750 unsigned ureg = reg;
1786 : out_buffer_(out_buffer) { }
1788 ~BufferDisassembler() { }
1799 : converter_(converter) {}
1802 Disassembler::~Disassembler() {
USE(converter_); }
1808 BufferDisassembler
disasm(buffer);
1809 decoder.AppendVisitor(&
disasm);
1816 int Disassembler::ConstantPoolSizeAt(
byte* instr) {
1822 void Disassembler::Disassemble(FILE*
file,
byte* start,
byte* end) {
1825 decoder.AppendVisitor(&
disasm);
Disassembler(const NameConverter &converter)
v8::internal::EmbeddedVector< char, 128 > tmp_buffer_
virtual const char * NameInCode(byte *addr) const
virtual const char * NameOfByteCPURegister(int reg) const
virtual const char * NameOfXMMRegister(int reg) const
virtual const char * NameOfAddress(byte *addr) const
virtual const char * NameOfCPURegister(int reg) const
virtual const char * NameOfConstant(byte *addr) const
static int ConstantPoolSizeAt(Instruction *instr)
virtual void Decode(Instruction *instr)
void Format(Instruction *instr, const char *mnemonic, const char *format)
int SubstituteBranchTargetField(Instruction *instr, const char *format)
int SubstituteExtendField(Instruction *instr, const char *format)
bool RnIsZROrSP(Instruction *instr) const
bool IsMovzMovnImm(unsigned reg_size, uint64_t value)
bool RdIsZROrSP(Instruction *instr) const
void AppendToOutput(const char *string,...)
int SubstituteField(Instruction *instr, const char *format)
bool RaIsZROrSP(Instruction *instr) const
int SubstituteLiteralField(Instruction *instr, const char *format)
bool RmIsZROrSP(Instruction *instr) const
int SubstituteConditionField(Instruction *instr, const char *format)
int SubstituteBitfieldImmediateField(Instruction *instr, const char *format)
int SubstituteImmediateField(Instruction *instr, const char *format)
int SubstitutePCRelAddressField(Instruction *instr, const char *format)
int SubstituteShiftField(Instruction *instr, const char *format)
int SubstituteRegisterField(Instruction *instr, const char *format)
int SubstituteLSRegOffsetField(Instruction *instr, const char *format)
int SubstituteBarrierField(Instruction *instr, const char *format)
void Substitute(Instruction *instr, const char *string)
int SubstitutePrefetchField(Instruction *instr, const char *format)
virtual void ProcessOutput(Instruction *instr)
virtual void ProcessOutput(Instruction *instr)
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes A file to write the raw context snapshot bytes Write V8 startup blob file(mksnapshot only)") DEFINE_BOOL(profile_hydrogen_code_stub_compilation
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
enable harmony numeric enable harmony object literal extensions Optimize object Array shift
#define DCHECK(condition)
@ UnconditionalBranchMask
@ DataProcessing1SourceMask
@ FPDataProcessing2SourceMask
const unsigned kXRegSizeInBits
@ LoadStorePairNonTemporalMask
@ LoadStorePairPreIndexMask
@ FPFixedPointConvertMask
@ LoadStoreUnscaledOffsetMask
int SNPrintF(Vector< char > str, const char *format,...)
const unsigned kWRegSizeInBits
@ FPDataProcessing3SourceMask
@ LoadStoreUnsignedOffsetMask
@ FPDataProcessing1SourceMask
const unsigned kLoadLiteralScaleLog2
@ LoadStorePairOffsetMask
Condition NegateCondition(Condition cond)
@ DataProcessing3SourceMask
@ DataProcessing2SourceMask
@ FPConditionalSelectMask
const unsigned kZeroRegCode
const unsigned kNumberOfRegisters
@ FPConditionalCompareMask
@ LoadStoreRegisterOffsetMask
const unsigned kInstructionSize
const unsigned kLinkRegCode
@ ConditionalCompareImmediateMask
const unsigned kInstructionSizeLog2
@ ConditionalCompareRegisterMask
@ UnconditionalBranchToRegisterMask
@ LoadStorePairPostIndexMask
Debugger support for the V8 JavaScript engine.