| 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 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 if ((instr & ~kImm16Mask) == 0) { | 656 if ((instr & ~kImm16Mask) == 0) { |
| 657 // Emitted label constant, not part of a branch. | 657 // Emitted label constant, not part of a branch. |
| 658 if (instr == 0) { | 658 if (instr == 0) { |
| 659 return kEndOfChain; | 659 return kEndOfChain; |
| 660 } else { | 660 } else { |
| 661 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; | 661 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; |
| 662 return (imm18 + pos); | 662 return (imm18 + pos); |
| 663 } | 663 } |
| 664 } | 664 } |
| 665 // Check we have a branch or jump instruction. | 665 // Check we have a branch or jump instruction. |
| 666 DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr)); | 666 DCHECK(IsBranch(instr) || IsLui(instr)); |
| 667 // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming | 667 // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming |
| 668 // the compiler uses arithmectic shifts for signed integers. | 668 // the compiler uses arithmectic shifts for signed integers. |
| 669 if (IsBranch(instr)) { | 669 if (IsBranch(instr)) { |
| 670 int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; | 670 int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; |
| 671 | 671 |
| 672 if (imm18 == kEndOfChain) { | 672 if (imm18 == kEndOfChain) { |
| 673 // EndOfChain sentinel is returned directly, not relative to pc or pos. | 673 // EndOfChain sentinel is returned directly, not relative to pc or pos. |
| 674 return kEndOfChain; | 674 return kEndOfChain; |
| 675 } else { | 675 } else { |
| 676 return pos + kBranchPCOffset + imm18; | 676 return pos + kBranchPCOffset + imm18; |
| 677 } | 677 } |
| 678 } else if (IsLui(instr)) { | 678 } else if (IsLui(instr)) { |
| 679 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); | 679 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); |
| 680 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); | 680 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); |
| 681 DCHECK(IsOri(instr_ori)); | 681 DCHECK(IsOri(instr_ori)); |
| 682 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift; | 682 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift; |
| 683 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask)); | 683 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask)); |
| 684 | 684 |
| 685 if (imm == kEndOfJumpChain) { | 685 if (imm == kEndOfJumpChain) { |
| 686 // EndOfChain sentinel is returned directly, not relative to pc or pos. | 686 // EndOfChain sentinel is returned directly, not relative to pc or pos. |
| 687 return kEndOfChain; | 687 return kEndOfChain; |
| 688 } else { | 688 } else { |
| 689 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); | 689 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); |
| 690 int32_t delta = instr_address - imm; | 690 int32_t delta = instr_address - imm; |
| 691 DCHECK(pos > delta); | 691 DCHECK(pos > delta); |
| 692 return pos - delta; | 692 return pos - delta; |
| 693 } | 693 } |
| 694 } else { | 694 } else { |
| 695 int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; | 695 UNREACHABLE(); |
| 696 if (imm28 == kEndOfJumpChain) { | 696 return 0; |
| 697 // EndOfChain sentinel is returned directly, not relative to pc or pos. | |
| 698 return kEndOfChain; | |
| 699 } else { | |
| 700 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); | |
| 701 instr_address &= kImm28Mask; | |
| 702 int delta = static_cast<int>(instr_address - imm28); | |
| 703 DCHECK(pos > delta); | |
| 704 return pos - delta; | |
| 705 } | |
| 706 } | 697 } |
| 707 } | 698 } |
| 708 | 699 |
| 709 | 700 |
| 710 void Assembler::target_at_put(int32_t pos, int32_t target_pos, | 701 void Assembler::target_at_put(int32_t pos, int32_t target_pos, |
| 711 bool is_internal) { | 702 bool is_internal) { |
| 712 Instr instr = instr_at(pos); | 703 Instr instr = instr_at(pos); |
| 713 | 704 |
| 714 if (is_internal) { | 705 if (is_internal) { |
| 715 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; | 706 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
| 716 instr_at_put(pos, imm); | 707 instr_at_put(pos, imm); |
| 717 return; | 708 return; |
| 718 } | 709 } |
| 719 if ((instr & ~kImm16Mask) == 0) { | 710 if ((instr & ~kImm16Mask) == 0) { |
| 720 DCHECK(target_pos == kEndOfChain || target_pos >= 0); | 711 DCHECK(target_pos == kEndOfChain || target_pos >= 0); |
| 721 // Emitted label constant, not part of a branch. | 712 // Emitted label constant, not part of a branch. |
| 722 // Make label relative to Code* of generated Code object. | 713 // Make label relative to Code* of generated Code object. |
| 723 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); | 714 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); |
| 724 return; | 715 return; |
| 725 } | 716 } |
| 726 | 717 |
| 727 DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr)); | 718 DCHECK(IsBranch(instr) || IsLui(instr)); |
| 728 if (IsBranch(instr)) { | 719 if (IsBranch(instr)) { |
| 729 int32_t imm18 = target_pos - (pos + kBranchPCOffset); | 720 int32_t imm18 = target_pos - (pos + kBranchPCOffset); |
| 730 DCHECK((imm18 & 3) == 0); | 721 DCHECK((imm18 & 3) == 0); |
| 731 | 722 |
| 732 instr &= ~kImm16Mask; | 723 instr &= ~kImm16Mask; |
| 733 int32_t imm16 = imm18 >> 2; | 724 int32_t imm16 = imm18 >> 2; |
| 734 DCHECK(is_int16(imm16)); | 725 DCHECK(is_int16(imm16)); |
| 735 | 726 |
| 736 instr_at_put(pos, instr | (imm16 & kImm16Mask)); | 727 instr_at_put(pos, instr | (imm16 & kImm16Mask)); |
| 737 } else if (IsLui(instr)) { | 728 } else if (IsLui(instr)) { |
| 738 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); | 729 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); |
| 739 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); | 730 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); |
| 740 DCHECK(IsOri(instr_ori)); | 731 DCHECK(IsOri(instr_ori)); |
| 741 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; | 732 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
| 742 DCHECK((imm & 3) == 0); | 733 DCHECK((imm & 3) == 0); |
| 743 | 734 |
| 744 instr_lui &= ~kImm16Mask; | 735 instr_lui &= ~kImm16Mask; |
| 745 instr_ori &= ~kImm16Mask; | 736 instr_ori &= ~kImm16Mask; |
| 746 | 737 |
| 747 instr_at_put(pos + 0 * Assembler::kInstrSize, | 738 instr_at_put(pos + 0 * Assembler::kInstrSize, |
| 748 instr_lui | ((imm & kHiMask) >> kLuiShift)); | 739 instr_lui | ((imm & kHiMask) >> kLuiShift)); |
| 749 instr_at_put(pos + 1 * Assembler::kInstrSize, | 740 instr_at_put(pos + 1 * Assembler::kInstrSize, |
| 750 instr_ori | (imm & kImm16Mask)); | 741 instr_ori | (imm & kImm16Mask)); |
| 751 } else { | 742 } else { |
| 752 uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos; | 743 UNREACHABLE(); |
| 753 imm28 &= kImm28Mask; | |
| 754 DCHECK((imm28 & 3) == 0); | |
| 755 | |
| 756 instr &= ~kImm26Mask; | |
| 757 uint32_t imm26 = imm28 >> 2; | |
| 758 DCHECK(is_uint26(imm26)); | |
| 759 | |
| 760 instr_at_put(pos, instr | (imm26 & kImm26Mask)); | |
| 761 } | 744 } |
| 762 } | 745 } |
| 763 | 746 |
| 764 | 747 |
| 765 void Assembler::print(Label* L) { | 748 void Assembler::print(Label* L) { |
| 766 if (L->is_unused()) { | 749 if (L->is_unused()) { |
| 767 PrintF("unused label\n"); | 750 PrintF("unused label\n"); |
| 768 } else if (L->is_bound()) { | 751 } else if (L->is_bound()) { |
| 769 PrintF("bound label to %d\n", L->pos()); | 752 PrintF("bound label to %d\n", L->pos()); |
| 770 } else if (L->is_linked()) { | 753 } else if (L->is_linked()) { |
| (...skipping 1640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2411 DCHECK((imm & 3) == 0); | 2394 DCHECK((imm & 3) == 0); |
| 2412 | 2395 |
| 2413 instr_lui &= ~kImm16Mask; | 2396 instr_lui &= ~kImm16Mask; |
| 2414 instr_ori &= ~kImm16Mask; | 2397 instr_ori &= ~kImm16Mask; |
| 2415 | 2398 |
| 2416 instr_at_put(pc + 0 * Assembler::kInstrSize, | 2399 instr_at_put(pc + 0 * Assembler::kInstrSize, |
| 2417 instr_lui | ((imm >> kLuiShift) & kImm16Mask)); | 2400 instr_lui | ((imm >> kLuiShift) & kImm16Mask)); |
| 2418 instr_at_put(pc + 1 * Assembler::kInstrSize, | 2401 instr_at_put(pc + 1 * Assembler::kInstrSize, |
| 2419 instr_ori | (imm & kImm16Mask)); | 2402 instr_ori | (imm & kImm16Mask)); |
| 2420 return 2; // Number of instructions patched. | 2403 return 2; // Number of instructions patched. |
| 2421 } else if (IsJ(instr)) { | |
| 2422 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; | |
| 2423 if (static_cast<int32_t>(imm28) == kEndOfJumpChain) { | |
| 2424 return 0; // Number of instructions patched. | |
| 2425 } | |
| 2426 imm28 += pc_delta; | |
| 2427 imm28 &= kImm28Mask; | |
| 2428 DCHECK((imm28 & 3) == 0); | |
| 2429 | |
| 2430 instr &= ~kImm26Mask; | |
| 2431 uint32_t imm26 = imm28 >> 2; | |
| 2432 DCHECK(is_uint26(imm26)); | |
| 2433 | |
| 2434 instr_at_put(pc, instr | (imm26 & kImm26Mask)); | |
| 2435 return 1; // Number of instructions patched. | |
| 2436 } else { | 2404 } else { |
| 2437 UNREACHABLE(); | 2405 UNREACHABLE(); |
| 2438 return 0; | 2406 return 0; |
| 2439 } | 2407 } |
| 2440 } | 2408 } |
| 2441 } | 2409 } |
| 2442 | 2410 |
| 2443 | 2411 |
| 2444 void Assembler::GrowBuffer() { | 2412 void Assembler::GrowBuffer() { |
| 2445 if (!own_buffer_) FATAL("external code buffer is too small"); | 2413 if (!own_buffer_) FATAL("external code buffer is too small"); |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2752 } | 2720 } |
| 2753 patched_jump = true; | 2721 patched_jump = true; |
| 2754 } | 2722 } |
| 2755 | 2723 |
| 2756 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 2724 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
| 2757 CpuFeatures::FlushICache(pc, (patched_jump ? 3 : 2) * sizeof(int32_t)); | 2725 CpuFeatures::FlushICache(pc, (patched_jump ? 3 : 2) * sizeof(int32_t)); |
| 2758 } | 2726 } |
| 2759 } | 2727 } |
| 2760 | 2728 |
| 2761 | 2729 |
| 2762 void Assembler::JumpLabelToJumpRegister(Address pc) { | 2730 void Assembler::JumpToJumpRegister(Address pc) { |
| 2763 // Address pc points to lui/ori instructions. | 2731 // Address pc points to lui/ori instructions. |
| 2764 // Jump to label may follow at pc + 2 * kInstrSize. | 2732 // Jump to label may follow at pc + 2 * kInstrSize. |
| 2765 uint32_t* p = reinterpret_cast<uint32_t*>(pc); | 2733 uint32_t* p = reinterpret_cast<uint32_t*>(pc); |
| 2766 #ifdef DEBUG | 2734 #ifdef DEBUG |
| 2767 Instr instr1 = instr_at(pc); | 2735 Instr instr1 = instr_at(pc); |
| 2768 #endif | 2736 #endif |
| 2769 Instr instr2 = instr_at(pc + 1 * kInstrSize); | 2737 Instr instr2 = instr_at(pc + 1 * kInstrSize); |
| 2770 Instr instr3 = instr_at(pc + 2 * kInstrSize); | 2738 Instr instr3 = instr_at(pc + 2 * kInstrSize); |
| 2771 bool patched = false; | 2739 bool patched = false; |
| 2772 | 2740 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2807 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { | 2775 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { |
| 2808 // No out-of-line constant pool support. | 2776 // No out-of-line constant pool support. |
| 2809 DCHECK(!FLAG_enable_ool_constant_pool); | 2777 DCHECK(!FLAG_enable_ool_constant_pool); |
| 2810 return; | 2778 return; |
| 2811 } | 2779 } |
| 2812 | 2780 |
| 2813 | 2781 |
| 2814 } } // namespace v8::internal | 2782 } } // namespace v8::internal |
| 2815 | 2783 |
| 2816 #endif // V8_TARGET_ARCH_MIPS | 2784 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |