OLD | NEW |
---|---|
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
404 // | 404 // |
405 // Label L; // unbound label | 405 // Label L; // unbound label |
406 // j(cc, &L); // forward branch to unbound label | 406 // j(cc, &L); // forward branch to unbound label |
407 // bind(&L); // bind label to the current pc | 407 // bind(&L); // bind label to the current pc |
408 // j(cc, &L); // backward branch to bound label | 408 // j(cc, &L); // backward branch to bound label |
409 // bind(&L); // illegal: a label may be bound only once | 409 // bind(&L); // illegal: a label may be bound only once |
410 // | 410 // |
411 // Note: The same Label can be used for forward and backward branches | 411 // Note: The same Label can be used for forward and backward branches |
412 // but it may be bound only once. | 412 // but it may be bound only once. |
413 void bind(Label* L); // Binds an unbound label L to current code position. | 413 void bind(Label* L); // Binds an unbound label L to current code position. |
414 | |
415 enum OffsetSize : int { kOffset26 = 26, kOffset21 = 21, kOffset16 = 16 }; | |
416 | |
414 // Determines if Label is bound and near enough so that branch instruction | 417 // Determines if Label is bound and near enough so that branch instruction |
415 // can be used to reach it, instead of jump instruction. | 418 // can be used to reach it, instead of jump instruction. |
416 bool is_near(Label* L); | 419 bool is_near(Label* L); |
420 bool is_near(Label* L, OffsetSize bits); | |
421 bool is_near_branch(Label* L); | |
422 inline bool is_near_pre_r6(Label* L) { | |
423 DCHECK(!(kArchVariant == kMips64r6)); | |
424 return pc_offset() - L->pos() < kMaxBranchOffset - 4 * kInstrSize; | |
425 } | |
426 inline bool is_near_r6(Label* L) { | |
427 DCHECK(kArchVariant == kMips64r6); | |
428 return pc_offset() - L->pos() < kMaxCompactBranchOffset - 4 * kInstrSize; | |
429 } | |
430 | |
431 int BranchOffset(Instr instr); | |
417 | 432 |
418 // Returns the branch offset to the given label from the current code | 433 // Returns the branch offset to the given label from the current code |
419 // position. Links the label to the current position if it is still unbound. | 434 // position. Links the label to the current position if it is still unbound. |
420 // Manages the jump elimination optimization if the second parameter is true. | 435 // Manages the jump elimination optimization if the second parameter is true. |
421 int32_t branch_offset(Label* L, bool jump_elimination_allowed); | 436 int32_t branch_offset_helper(Label* L, OffsetSize bits); |
422 int32_t branch_offset_compact(Label* L, bool jump_elimination_allowed); | 437 inline int32_t branch_offset(Label* L) { |
423 int32_t branch_offset21(Label* L, bool jump_elimination_allowed); | 438 return branch_offset_helper(L, OffsetSize::kOffset16); |
424 int32_t branch_offset21_compact(Label* L, bool jump_elimination_allowed); | |
425 int32_t shifted_branch_offset(Label* L, bool jump_elimination_allowed) { | |
426 int32_t o = branch_offset(L, jump_elimination_allowed); | |
427 DCHECK((o & 3) == 0); // Assert the offset is aligned. | |
428 return o >> 2; | |
429 } | 439 } |
430 int32_t shifted_branch_offset_compact(Label* L, | 440 inline int32_t branch_offset21(Label* L) { |
431 bool jump_elimination_allowed) { | 441 return branch_offset_helper(L, OffsetSize::kOffset21); |
432 int32_t o = branch_offset_compact(L, jump_elimination_allowed); | 442 } |
433 DCHECK((o & 3) == 0); // Assert the offset is aligned. | 443 inline int32_t branch_offset26(Label* L) { |
434 return o >> 2; | 444 return branch_offset_helper(L, OffsetSize::kOffset26); |
445 } | |
446 inline int32_t shifted_branch_offset(Label* L) { | |
447 return branch_offset(L) >> 2; | |
448 } | |
449 inline int32_t shifted_branch_offset21(Label* L) { | |
450 return branch_offset21(L) >> 2; | |
451 } | |
452 inline int32_t shifted_branch_offset26(Label* L) { | |
453 return branch_offset26(L) >> 2; | |
435 } | 454 } |
436 uint64_t jump_address(Label* L); | 455 uint64_t jump_address(Label* L); |
437 uint64_t jump_offset(Label* L); | 456 uint64_t jump_offset(Label* L); |
438 | 457 |
439 // Puts a labels target address at the given position. | 458 // Puts a labels target address at the given position. |
440 // The high 8 bits are set to zero. | 459 // The high 8 bits are set to zero. |
441 void label_at_put(Label* L, int at_offset); | 460 void label_at_put(Label* L, int at_offset); |
442 | 461 |
443 // Read/Modify the code target address in the branch/call instruction at pc. | 462 // Read/Modify the code target address in the branch/call instruction at pc. |
444 static Address target_address_at(Address pc); | 463 static Address target_address_at(Address pc); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 void nop(unsigned int type = 0) { | 584 void nop(unsigned int type = 0) { |
566 DCHECK(type < 32); | 585 DCHECK(type < 32); |
567 Register nop_rt_reg = (type == 0) ? zero_reg : at; | 586 Register nop_rt_reg = (type == 0) ? zero_reg : at; |
568 sll(zero_reg, nop_rt_reg, type, true); | 587 sll(zero_reg, nop_rt_reg, type, true); |
569 } | 588 } |
570 | 589 |
571 | 590 |
572 // --------Branch-and-jump-instructions---------- | 591 // --------Branch-and-jump-instructions---------- |
573 // We don't use likely variant of instructions. | 592 // We don't use likely variant of instructions. |
574 void b(int16_t offset); | 593 void b(int16_t offset); |
575 void b(Label* L) { b(branch_offset(L, false)>>2); } | 594 inline void b(Label* L) { b(shifted_branch_offset(L)); } |
576 void bal(int16_t offset); | 595 void bal(int16_t offset); |
577 void bal(Label* L) { bal(branch_offset(L, false)>>2); } | 596 inline void bal(Label* L) { bal(shifted_branch_offset(L)); } |
578 void bc(int32_t offset); | 597 void bc(int32_t offset); |
579 void bc(Label* L) { bc(branch_offset(L, false) >> 2); } | 598 inline void bc(Label* L) { bc(shifted_branch_offset26(L)); } |
580 void balc(int32_t offset); | 599 void balc(int32_t offset); |
581 void balc(Label* L) { balc(branch_offset(L, false) >> 2); } | 600 inline void balc(Label* L) { balc(shifted_branch_offset26(L)); } |
582 | 601 |
583 void beq(Register rs, Register rt, int16_t offset); | 602 void beq(Register rs, Register rt, int16_t offset); |
584 void beq(Register rs, Register rt, Label* L) { | 603 inline void beq(Register rs, Register rt, Label* L) { |
585 beq(rs, rt, branch_offset(L, false) >> 2); | 604 beq(rs, rt, shifted_branch_offset(L)); |
586 } | 605 } |
587 void bgez(Register rs, int16_t offset); | 606 void bgez(Register rs, int16_t offset); |
588 void bgezc(Register rt, int16_t offset); | 607 void bgezc(Register rt, int16_t offset); |
589 void bgezc(Register rt, Label* L) { | 608 inline void bgezc(Register rt, Label* L) { |
590 bgezc(rt, branch_offset_compact(L, false)>>2); | 609 bgezc(rt, shifted_branch_offset(L)); |
591 } | 610 } |
592 void bgeuc(Register rs, Register rt, int16_t offset); | 611 void bgeuc(Register rs, Register rt, int16_t offset); |
593 void bgeuc(Register rs, Register rt, Label* L) { | 612 inline void bgeuc(Register rs, Register rt, Label* L) { |
594 bgeuc(rs, rt, branch_offset_compact(L, false)>>2); | 613 bgeuc(rs, rt, shifted_branch_offset(L)); |
595 } | 614 } |
596 void bgec(Register rs, Register rt, int16_t offset); | 615 void bgec(Register rs, Register rt, int16_t offset); |
597 void bgec(Register rs, Register rt, Label* L) { | 616 inline void bgec(Register rs, Register rt, Label* L) { |
598 bgec(rs, rt, branch_offset_compact(L, false)>>2); | 617 bgec(rs, rt, shifted_branch_offset(L)); |
599 } | 618 } |
600 void bgezal(Register rs, int16_t offset); | 619 void bgezal(Register rs, int16_t offset); |
601 void bgezalc(Register rt, int16_t offset); | 620 void bgezalc(Register rt, int16_t offset); |
602 void bgezalc(Register rt, Label* L) { | 621 inline void bgezalc(Register rt, Label* L) { |
603 bgezalc(rt, branch_offset_compact(L, false)>>2); | 622 bgezalc(rt, shifted_branch_offset(L)); |
604 } | 623 } |
605 void bgezall(Register rs, int16_t offset); | 624 void bgezall(Register rs, int16_t offset); |
606 void bgezall(Register rs, Label* L) { | 625 inline void bgezall(Register rs, Label* L) { |
607 bgezall(rs, branch_offset(L, false)>>2); | 626 bgezall(rs, branch_offset(L) >> 2); |
608 } | 627 } |
609 void bgtz(Register rs, int16_t offset); | 628 void bgtz(Register rs, int16_t offset); |
610 void bgtzc(Register rt, int16_t offset); | 629 void bgtzc(Register rt, int16_t offset); |
611 void bgtzc(Register rt, Label* L) { | 630 inline void bgtzc(Register rt, Label* L) { |
612 bgtzc(rt, branch_offset_compact(L, false)>>2); | 631 bgtzc(rt, shifted_branch_offset(L)); |
613 } | 632 } |
614 void blez(Register rs, int16_t offset); | 633 void blez(Register rs, int16_t offset); |
615 void blezc(Register rt, int16_t offset); | 634 void blezc(Register rt, int16_t offset); |
616 void blezc(Register rt, Label* L) { | 635 inline void blezc(Register rt, Label* L) { |
617 blezc(rt, branch_offset_compact(L, false)>>2); | 636 blezc(rt, shifted_branch_offset(L)); |
618 } | 637 } |
619 void bltz(Register rs, int16_t offset); | 638 void bltz(Register rs, int16_t offset); |
620 void bltzc(Register rt, int16_t offset); | 639 void bltzc(Register rt, int16_t offset); |
621 void bltzc(Register rt, Label* L) { | 640 inline void bltzc(Register rt, Label* L) { |
622 bltzc(rt, branch_offset_compact(L, false)>>2); | 641 bltzc(rt, shifted_branch_offset(L)); |
623 } | 642 } |
624 void bltuc(Register rs, Register rt, int16_t offset); | 643 void bltuc(Register rs, Register rt, int16_t offset); |
625 void bltuc(Register rs, Register rt, Label* L) { | 644 inline void bltuc(Register rs, Register rt, Label* L) { |
626 bltuc(rs, rt, branch_offset_compact(L, false)>>2); | 645 bltuc(rs, rt, shifted_branch_offset(L)); |
627 } | 646 } |
628 void bltc(Register rs, Register rt, int16_t offset); | 647 void bltc(Register rs, Register rt, int16_t offset); |
629 void bltc(Register rs, Register rt, Label* L) { | 648 inline void bltc(Register rs, Register rt, Label* L) { |
630 bltc(rs, rt, branch_offset_compact(L, false)>>2); | 649 bltc(rs, rt, shifted_branch_offset(L)); |
631 } | 650 } |
632 | |
633 void bltzal(Register rs, int16_t offset); | 651 void bltzal(Register rs, int16_t offset); |
634 void blezalc(Register rt, int16_t offset); | 652 void blezalc(Register rt, int16_t offset); |
635 void blezalc(Register rt, Label* L) { | 653 inline void blezalc(Register rt, Label* L) { |
636 blezalc(rt, branch_offset_compact(L, false)>>2); | 654 blezalc(rt, shifted_branch_offset(L)); |
637 } | 655 } |
638 void bltzalc(Register rt, int16_t offset); | 656 void bltzalc(Register rt, int16_t offset); |
639 void bltzalc(Register rt, Label* L) { | 657 inline void bltzalc(Register rt, Label* L) { |
640 bltzalc(rt, branch_offset_compact(L, false)>>2); | 658 bltzalc(rt, shifted_branch_offset(L)); |
641 } | 659 } |
642 void bgtzalc(Register rt, int16_t offset); | 660 void bgtzalc(Register rt, int16_t offset); |
643 void bgtzalc(Register rt, Label* L) { | 661 inline void bgtzalc(Register rt, Label* L) { |
644 bgtzalc(rt, branch_offset_compact(L, false)>>2); | 662 bgtzalc(rt, shifted_branch_offset(L)); |
645 } | 663 } |
646 void beqzalc(Register rt, int16_t offset); | 664 void beqzalc(Register rt, int16_t offset); |
647 void beqzalc(Register rt, Label* L) { | 665 inline void beqzalc(Register rt, Label* L) { |
648 beqzalc(rt, branch_offset_compact(L, false)>>2); | 666 beqzalc(rt, shifted_branch_offset(L)); |
649 } | 667 } |
650 void beqc(Register rs, Register rt, int16_t offset); | 668 void beqc(Register rs, Register rt, int16_t offset); |
651 void beqc(Register rs, Register rt, Label* L) { | 669 inline void beqc(Register rs, Register rt, Label* L) { |
652 beqc(rs, rt, branch_offset_compact(L, false)>>2); | 670 beqc(rs, rt, shifted_branch_offset(L)); |
653 } | 671 } |
654 void beqzc(Register rs, int32_t offset); | 672 void beqzc(Register rs, int32_t offset); |
655 void beqzc(Register rs, Label* L) { | 673 inline void beqzc(Register rs, Label* L) { |
656 beqzc(rs, branch_offset21_compact(L, false)>>2); | 674 beqzc(rs, shifted_branch_offset21(L)); |
657 } | 675 } |
658 void bnezalc(Register rt, int16_t offset); | 676 void bnezalc(Register rt, int16_t offset); |
659 void bnezalc(Register rt, Label* L) { | 677 inline void bnezalc(Register rt, Label* L) { |
660 bnezalc(rt, branch_offset_compact(L, false)>>2); | 678 bnezalc(rt, shifted_branch_offset(L)); |
661 } | 679 } |
662 void bnec(Register rs, Register rt, int16_t offset); | 680 void bnec(Register rs, Register rt, int16_t offset); |
663 void bnec(Register rs, Register rt, Label* L) { | 681 inline void bnec(Register rs, Register rt, Label* L) { |
664 bnec(rs, rt, branch_offset_compact(L, false)>>2); | 682 bnec(rs, rt, shifted_branch_offset(L)); |
665 } | 683 } |
666 void bnezc(Register rt, int32_t offset); | 684 void bnezc(Register rt, int32_t offset); |
667 void bnezc(Register rt, Label* L) { | 685 inline void bnezc(Register rt, Label* L) { |
668 bnezc(rt, branch_offset21_compact(L, false)>>2); | 686 bnezc(rt, shifted_branch_offset21(L)); |
669 } | 687 } |
670 void bne(Register rs, Register rt, int16_t offset); | 688 void bne(Register rs, Register rt, int16_t offset); |
671 void bne(Register rs, Register rt, Label* L) { | 689 inline void bne(Register rs, Register rt, Label* L) { |
672 bne(rs, rt, branch_offset(L, false)>>2); | 690 bne(rs, rt, shifted_branch_offset(L)); |
673 } | 691 } |
674 void bovc(Register rs, Register rt, int16_t offset); | 692 void bovc(Register rs, Register rt, int16_t offset); |
675 void bovc(Register rs, Register rt, Label* L) { | 693 inline void bovc(Register rs, Register rt, Label* L) { |
676 bovc(rs, rt, branch_offset_compact(L, false)>>2); | 694 bovc(rs, rt, shifted_branch_offset(L)); |
677 } | 695 } |
678 void bnvc(Register rs, Register rt, int16_t offset); | 696 void bnvc(Register rs, Register rt, int16_t offset); |
679 void bnvc(Register rs, Register rt, Label* L) { | 697 inline void bnvc(Register rs, Register rt, Label* L) { |
680 bnvc(rs, rt, branch_offset_compact(L, false)>>2); | 698 bnvc(rs, rt, shifted_branch_offset(L)); |
681 } | 699 } |
682 | 700 |
683 // Never use the int16_t b(l)cond version with a branch offset | 701 // Never use the int16_t b(l)cond version with a branch offset |
684 // instead of using the Label* version. | 702 // instead of using the Label* version. |
685 | 703 |
686 // Jump targets must be in the current 256 MB-aligned region. i.e. 28 bits. | 704 // Jump targets must be in the current 256 MB-aligned region. i.e. 28 bits. |
687 void j(int64_t target); | 705 void j(int64_t target); |
688 void jal(int64_t target); | 706 void jal(int64_t target); |
689 void j(Label* target); | 707 void j(Label* target); |
690 void jal(Label* target); | 708 void jal(Label* target); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
965 void cvt_d_l(FPURegister fd, FPURegister fs); | 983 void cvt_d_l(FPURegister fd, FPURegister fs); |
966 void cvt_d_s(FPURegister fd, FPURegister fs); | 984 void cvt_d_s(FPURegister fd, FPURegister fs); |
967 | 985 |
968 // Conditions and branches for MIPSr6. | 986 // Conditions and branches for MIPSr6. |
969 void cmp(FPUCondition cond, SecondaryField fmt, | 987 void cmp(FPUCondition cond, SecondaryField fmt, |
970 FPURegister fd, FPURegister ft, FPURegister fs); | 988 FPURegister fd, FPURegister ft, FPURegister fs); |
971 void cmp_s(FPUCondition cond, FPURegister fd, FPURegister fs, FPURegister ft); | 989 void cmp_s(FPUCondition cond, FPURegister fd, FPURegister fs, FPURegister ft); |
972 void cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs, FPURegister ft); | 990 void cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs, FPURegister ft); |
973 | 991 |
974 void bc1eqz(int16_t offset, FPURegister ft); | 992 void bc1eqz(int16_t offset, FPURegister ft); |
975 void bc1eqz(Label* L, FPURegister ft) { | 993 inline void bc1eqz(Label* L, FPURegister ft) { |
976 bc1eqz(branch_offset(L, false)>>2, ft); | 994 bc1eqz(shifted_branch_offset(L), ft); |
977 } | 995 } |
978 void bc1nez(int16_t offset, FPURegister ft); | 996 void bc1nez(int16_t offset, FPURegister ft); |
979 void bc1nez(Label* L, FPURegister ft) { | 997 inline void bc1nez(Label* L, FPURegister ft) { |
980 bc1nez(branch_offset(L, false)>>2, ft); | 998 bc1nez(shifted_branch_offset(L), ft); |
981 } | 999 } |
982 | 1000 |
983 // Conditions and branches for non MIPSr6. | 1001 // Conditions and branches for non MIPSr6. |
984 void c(FPUCondition cond, SecondaryField fmt, | 1002 void c(FPUCondition cond, SecondaryField fmt, |
985 FPURegister ft, FPURegister fs, uint16_t cc = 0); | 1003 FPURegister ft, FPURegister fs, uint16_t cc = 0); |
986 void c_s(FPUCondition cond, FPURegister ft, FPURegister fs, uint16_t cc = 0); | 1004 void c_s(FPUCondition cond, FPURegister ft, FPURegister fs, uint16_t cc = 0); |
987 void c_d(FPUCondition cond, FPURegister ft, FPURegister fs, uint16_t cc = 0); | 1005 void c_d(FPUCondition cond, FPURegister ft, FPURegister fs, uint16_t cc = 0); |
988 | 1006 |
989 void bc1f(int16_t offset, uint16_t cc = 0); | 1007 void bc1f(int16_t offset, uint16_t cc = 0); |
990 void bc1f(Label* L, uint16_t cc = 0) { | 1008 inline void bc1f(Label* L, uint16_t cc = 0) { |
991 bc1f(branch_offset(L, false)>>2, cc); | 1009 bc1f(shifted_branch_offset(L), cc); |
992 } | 1010 } |
993 void bc1t(int16_t offset, uint16_t cc = 0); | 1011 void bc1t(int16_t offset, uint16_t cc = 0); |
994 void bc1t(Label* L, uint16_t cc = 0) { | 1012 inline void bc1t(Label* L, uint16_t cc = 0) { |
995 bc1t(branch_offset(L, false)>>2, cc); | 1013 bc1t(shifted_branch_offset(L), cc); |
996 } | 1014 } |
997 void fcmp(FPURegister src1, const double src2, FPUCondition cond); | 1015 void fcmp(FPURegister src1, const double src2, FPUCondition cond); |
998 | 1016 |
999 // Check the code size generated from label to here. | 1017 // Check the code size generated from label to here. |
1000 int SizeOfCodeGeneratedSince(Label* label) { | 1018 int SizeOfCodeGeneratedSince(Label* label) { |
1001 return pc_offset() - label->pos(); | 1019 return pc_offset() - label->pos(); |
1002 } | 1020 } |
1003 | 1021 |
1004 // Check the number of instructions generated from label to here. | 1022 // Check the number of instructions generated from label to here. |
1005 int InstructionsGeneratedSince(Label* label) { | 1023 int InstructionsGeneratedSince(Label* label) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1106 static void instr_at_put(byte* pc, Instr instr) { | 1124 static void instr_at_put(byte* pc, Instr instr) { |
1107 *reinterpret_cast<Instr*>(pc) = instr; | 1125 *reinterpret_cast<Instr*>(pc) = instr; |
1108 } | 1126 } |
1109 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } | 1127 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } |
1110 void instr_at_put(int pos, Instr instr) { | 1128 void instr_at_put(int pos, Instr instr) { |
1111 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; | 1129 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; |
1112 } | 1130 } |
1113 | 1131 |
1114 // Check if an instruction is a branch of some kind. | 1132 // Check if an instruction is a branch of some kind. |
1115 static bool IsBranch(Instr instr); | 1133 static bool IsBranch(Instr instr); |
1134 static bool IsBc(Instr instr); | |
1135 static bool IsBzc(Instr instr); | |
1136 | |
1116 static bool IsBeq(Instr instr); | 1137 static bool IsBeq(Instr instr); |
1117 static bool IsBne(Instr instr); | 1138 static bool IsBne(Instr instr); |
1139 static bool IsBeqzc(Instr instr); | |
1140 static bool IsBnezc(Instr instr); | |
1141 static bool IsBeqc(Instr instr); | |
1142 static bool IsBnec(Instr instr); | |
1143 | |
1118 | 1144 |
1119 static bool IsJump(Instr instr); | 1145 static bool IsJump(Instr instr); |
1120 static bool IsJ(Instr instr); | 1146 static bool IsJ(Instr instr); |
1121 static bool IsLui(Instr instr); | 1147 static bool IsLui(Instr instr); |
1122 static bool IsOri(Instr instr); | 1148 static bool IsOri(Instr instr); |
1123 | 1149 |
1124 static bool IsJal(Instr instr); | 1150 static bool IsJal(Instr instr); |
1125 static bool IsJr(Instr instr); | 1151 static bool IsJr(Instr instr); |
1126 static bool IsJalr(Instr instr); | 1152 static bool IsJalr(Instr instr); |
1127 | 1153 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1166 | 1192 |
1167 void CheckTrampolinePool(); | 1193 void CheckTrampolinePool(); |
1168 | 1194 |
1169 void PatchConstantPoolAccessInstruction(int pc_offset, int offset, | 1195 void PatchConstantPoolAccessInstruction(int pc_offset, int offset, |
1170 ConstantPoolEntry::Access access, | 1196 ConstantPoolEntry::Access access, |
1171 ConstantPoolEntry::Type type) { | 1197 ConstantPoolEntry::Type type) { |
1172 // No embedded constant pool support. | 1198 // No embedded constant pool support. |
1173 UNREACHABLE(); | 1199 UNREACHABLE(); |
1174 } | 1200 } |
1175 | 1201 |
1202 bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; } | |
1203 | |
1176 protected: | 1204 protected: |
1177 // Relocation for a type-recording IC has the AST id added to it. This | 1205 // Relocation for a type-recording IC has the AST id added to it. This |
1178 // member variable is a way to pass the information from the call site to | 1206 // member variable is a way to pass the information from the call site to |
1179 // the relocation info. | 1207 // the relocation info. |
1180 TypeFeedbackId recorded_ast_id_; | 1208 TypeFeedbackId recorded_ast_id_; |
1181 | 1209 |
1182 inline static void set_target_internal_reference_encoded_at(Address pc, | 1210 inline static void set_target_internal_reference_encoded_at(Address pc, |
1183 Address target); | 1211 Address target); |
1184 | 1212 |
1185 int64_t buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1213 int64_t buffer_space() const { return reloc_info_writer.pos() - pc_; } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1232 | 1260 |
1233 void EndBlockGrowBuffer() { | 1261 void EndBlockGrowBuffer() { |
1234 DCHECK(block_buffer_growth_); | 1262 DCHECK(block_buffer_growth_); |
1235 block_buffer_growth_ = false; | 1263 block_buffer_growth_ = false; |
1236 } | 1264 } |
1237 | 1265 |
1238 bool is_buffer_growth_blocked() const { | 1266 bool is_buffer_growth_blocked() const { |
1239 return block_buffer_growth_; | 1267 return block_buffer_growth_; |
1240 } | 1268 } |
1241 | 1269 |
1270 void EmitPendingInstructions() { | |
balazs.kilvady
2015/12/18 19:18:05
Nice solution. Should be backported to 32-bit. Alt
ivica.bogosavljevic
2015/12/22 10:22:39
I was thinking the same thing as you did, to use t
balazs.kilvady
2015/12/22 11:01:56
I don't agree. Actually Assembler class is for dir
ivica.bogosavljevic
2015/12/22 12:23:41
Acknowledged.
| |
1271 if (IsPrevInstrCompactBranch()) { | |
1272 nop(); | |
1273 ClearCompactBranchState(); | |
1274 } | |
1275 } | |
1276 | |
1277 inline void CheckTrampolinePoolQuick(int extra_instructions = 0); | |
1278 | |
1242 private: | 1279 private: |
1243 // Buffer size and constant pool distance are checked together at regular | 1280 // Buffer size and constant pool distance are checked together at regular |
1244 // intervals of kBufferCheckInterval emitted bytes. | 1281 // intervals of kBufferCheckInterval emitted bytes. |
1245 static const int kBufferCheckInterval = 1*KB/2; | 1282 static const int kBufferCheckInterval = 1*KB/2; |
1246 | 1283 |
1247 // Code generation. | 1284 // Code generation. |
1248 // The relocation writer's position is at least kGap bytes below the end of | 1285 // The relocation writer's position is at least kGap bytes below the end of |
1249 // the generated instructions. This is so that multi-instruction sequences do | 1286 // the generated instructions. This is so that multi-instruction sequences do |
1250 // not have to check for overflow. The same is true for writes of large | 1287 // not have to check for overflow. The same is true for writes of large |
1251 // relocation info entries. | 1288 // relocation info entries. |
(...skipping 19 matching lines...) Expand all Loading... | |
1271 bool block_buffer_growth_; // Block growth when true. | 1308 bool block_buffer_growth_; // Block growth when true. |
1272 | 1309 |
1273 // Relocation information generation. | 1310 // Relocation information generation. |
1274 // Each relocation is encoded as a variable size value. | 1311 // Each relocation is encoded as a variable size value. |
1275 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 1312 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
1276 RelocInfoWriter reloc_info_writer; | 1313 RelocInfoWriter reloc_info_writer; |
1277 | 1314 |
1278 // The bound position, before this we cannot do instruction elimination. | 1315 // The bound position, before this we cannot do instruction elimination. |
1279 int last_bound_pos_; | 1316 int last_bound_pos_; |
1280 | 1317 |
1318 // Readable constants for compact branch handling in emit() | |
1319 enum class CompactBranchType : bool { NO = false, COMPACT_BRANCH = true }; | |
1320 | |
1281 // Code emission. | 1321 // Code emission. |
1282 inline void CheckBuffer(); | 1322 inline void CheckBuffer(); |
1283 void GrowBuffer(); | 1323 void GrowBuffer(); |
1284 inline void emit(Instr x); | 1324 inline void emit(Instr x, |
1285 inline void emit(uint64_t x); | 1325 CompactBranchType is_compact_branch = CompactBranchType::NO); |
1286 inline void CheckTrampolinePoolQuick(int extra_instructions = 0); | 1326 inline void emit(uint64_t x, |
1327 CompactBranchType is_compact_branch = CompactBranchType::NO); | |
1287 | 1328 |
balazs.kilvady
2015/12/18 19:18:05
A 64-bit value cannot be a real instruction so it
ivica.bogosavljevic
2015/12/22 10:22:39
Acknowledged.
| |
1288 // Instruction generation. | 1329 // Instruction generation. |
1289 // We have 3 different kind of encoding layout on MIPS. | 1330 // We have 3 different kind of encoding layout on MIPS. |
1290 // However due to many different types of objects encoded in the same fields | 1331 // However due to many different types of objects encoded in the same fields |
1291 // we have quite a few aliases for each mode. | 1332 // we have quite a few aliases for each mode. |
1292 // Using the same structure to refer to Register and FPURegister would spare a | 1333 // Using the same structure to refer to Register and FPURegister would spare a |
1293 // few aliases, but mixing both does not look clean to me. | 1334 // few aliases, but mixing both does not look clean to me. |
1294 // Anyway we could surely implement this differently. | 1335 // Anyway we could surely implement this differently. |
1295 | 1336 |
1296 void GenInstrRegister(Opcode opcode, | 1337 void GenInstrRegister(Opcode opcode, |
1297 Register rs, | 1338 Register rs, |
(...skipping 30 matching lines...) Expand all Loading... | |
1328 FPURegister fd, | 1369 FPURegister fd, |
1329 SecondaryField func = NULLSF); | 1370 SecondaryField func = NULLSF); |
1330 | 1371 |
1331 void GenInstrRegister(Opcode opcode, | 1372 void GenInstrRegister(Opcode opcode, |
1332 SecondaryField fmt, | 1373 SecondaryField fmt, |
1333 Register rt, | 1374 Register rt, |
1334 FPUControlRegister fs, | 1375 FPUControlRegister fs, |
1335 SecondaryField func = NULLSF); | 1376 SecondaryField func = NULLSF); |
1336 | 1377 |
1337 | 1378 |
1338 void GenInstrImmediate(Opcode opcode, | 1379 void GenInstrImmediate( |
1339 Register rs, | 1380 Opcode opcode, Register rs, Register rt, int32_t j, |
1340 Register rt, | 1381 CompactBranchType is_compact_branch = CompactBranchType::NO); |
1341 int32_t j); | 1382 void GenInstrImmediate( |
1342 void GenInstrImmediate(Opcode opcode, | 1383 Opcode opcode, Register rs, SecondaryField SF, int32_t j, |
1343 Register rs, | 1384 CompactBranchType is_compact_branch = CompactBranchType::NO); |
1344 SecondaryField SF, | 1385 void GenInstrImmediate( |
1345 int32_t j); | 1386 Opcode opcode, Register r1, FPURegister r2, int32_t j, |
1346 void GenInstrImmediate(Opcode opcode, | 1387 CompactBranchType is_compact_branch = CompactBranchType::NO); |
1347 Register r1, | 1388 void GenInstrImmediate( |
1348 FPURegister r2, | 1389 Opcode opcode, Register rs, int32_t offset21, |
1349 int32_t j); | 1390 CompactBranchType is_compact_branch = CompactBranchType::NO); |
1350 void GenInstrImmediate(Opcode opcode, Register rs, int32_t j); | 1391 void GenInstrImmediate(Opcode opcode, Register rs, uint32_t offset21); |
1351 void GenInstrImmediate(Opcode opcode, int32_t offset26); | 1392 void GenInstrImmediate( |
1352 | 1393 Opcode opcode, int32_t offset26, |
1394 CompactBranchType is_compact_branch = CompactBranchType::NO); | |
1353 | 1395 |
1354 void GenInstrJump(Opcode opcode, | 1396 void GenInstrJump(Opcode opcode, |
1355 uint32_t address); | 1397 uint32_t address); |
1356 | 1398 |
1357 // Helpers. | 1399 // Helpers. |
1358 void LoadRegPlusOffsetToAt(const MemOperand& src); | 1400 void LoadRegPlusOffsetToAt(const MemOperand& src); |
1359 | 1401 |
1360 // Labels. | 1402 // Labels. |
1361 void print(Label* L); | 1403 void print(Label* L); |
1362 void bind_to(Label* L, int pos); | 1404 void bind_to(Label* L, int pos); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1416 int32_t get_trampoline_entry(int32_t pos); | 1458 int32_t get_trampoline_entry(int32_t pos); |
1417 int unbound_labels_count_; | 1459 int unbound_labels_count_; |
1418 // After trampoline is emitted, long branches are used in generated code for | 1460 // After trampoline is emitted, long branches are used in generated code for |
1419 // the forward branches whose target offsets could be beyond reach of branch | 1461 // the forward branches whose target offsets could be beyond reach of branch |
1420 // instruction. We use this information to trigger different mode of | 1462 // instruction. We use this information to trigger different mode of |
1421 // branch instruction generation, where we use jump instructions rather | 1463 // branch instruction generation, where we use jump instructions rather |
1422 // than regular branch instructions. | 1464 // than regular branch instructions. |
1423 bool trampoline_emitted_; | 1465 bool trampoline_emitted_; |
1424 static const int kTrampolineSlotsSize = 2 * kInstrSize; | 1466 static const int kTrampolineSlotsSize = 2 * kInstrSize; |
1425 static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; | 1467 static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; |
1468 static const int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1; | |
1426 static const int kInvalidSlotPos = -1; | 1469 static const int kInvalidSlotPos = -1; |
1427 | 1470 |
1428 // Internal reference positions, required for unbounded internal reference | 1471 // Internal reference positions, required for unbounded internal reference |
1429 // labels. | 1472 // labels. |
1430 std::set<int64_t> internal_reference_positions_; | 1473 std::set<int64_t> internal_reference_positions_; |
1431 | 1474 |
1475 void EmittedCompactBranchInstruction() { prev_instr_compact_branch_ = true; } | |
1476 void ClearCompactBranchState() { prev_instr_compact_branch_ = false; } | |
1477 bool prev_instr_compact_branch_ = false; | |
1478 | |
1432 Trampoline trampoline_; | 1479 Trampoline trampoline_; |
1433 bool internal_trampoline_exception_; | 1480 bool internal_trampoline_exception_; |
1434 | 1481 |
1435 friend class RegExpMacroAssemblerMIPS; | 1482 friend class RegExpMacroAssemblerMIPS; |
1436 friend class RelocInfo; | 1483 friend class RelocInfo; |
1437 friend class CodePatcher; | 1484 friend class CodePatcher; |
1438 friend class BlockTrampolinePoolScope; | 1485 friend class BlockTrampolinePoolScope; |
1439 | 1486 |
1440 PositionsRecorder positions_recorder_; | 1487 PositionsRecorder positions_recorder_; |
1441 friend class PositionsRecorder; | 1488 friend class PositionsRecorder; |
1442 friend class EnsureSpace; | 1489 friend class EnsureSpace; |
1443 }; | 1490 }; |
1444 | 1491 |
1445 | 1492 |
1446 class EnsureSpace BASE_EMBEDDED { | 1493 class EnsureSpace BASE_EMBEDDED { |
1447 public: | 1494 public: |
1448 explicit EnsureSpace(Assembler* assembler) { | 1495 explicit EnsureSpace(Assembler* assembler) { |
1449 assembler->CheckBuffer(); | 1496 assembler->CheckBuffer(); |
1450 } | 1497 } |
1451 }; | 1498 }; |
1452 | 1499 |
1453 } // namespace internal | 1500 } // namespace internal |
1454 } // namespace v8 | 1501 } // namespace v8 |
1455 | 1502 |
1456 #endif // V8_ARM_ASSEMBLER_MIPS_H_ | 1503 #endif // V8_ARM_ASSEMBLER_MIPS_H_ |
OLD | NEW |