OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // | 2 // |
3 // Redistribution and use in source and binary forms, with or without | 3 // Redistribution and use in source and binary forms, with or without |
4 // modification, are permitted provided that the following conditions are | 4 // modification, are permitted provided that the following conditions are |
5 // met: | 5 // met: |
6 // | 6 // |
7 // * Redistributions of source code must retain the above copyright | 7 // * Redistributions of source code must retain the above copyright |
8 // notice, this list of conditions and the following disclaimer. | 8 // notice, this list of conditions and the following disclaimer. |
9 // * Redistributions in binary form must reproduce the above | 9 // * Redistributions in binary form must reproduce the above |
10 // copyright notice, this list of conditions and the following | 10 // copyright notice, this list of conditions and the following |
(...skipping 2790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2801 return NULL; | 2801 return NULL; |
2802 } | 2802 } |
2803 | 2803 |
2804 | 2804 |
2805 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { | 2805 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { |
2806 // No out-of-line constant pool support. | 2806 // No out-of-line constant pool support. |
2807 UNREACHABLE(); | 2807 UNREACHABLE(); |
2808 } | 2808 } |
2809 | 2809 |
2810 | 2810 |
| 2811 void PatchingAssembler::MovInt64(const Register& rd, int64_t imm) { |
| 2812 Label start; |
| 2813 bind(&start); |
| 2814 |
| 2815 ASSERT(rd.Is64Bits()); |
| 2816 ASSERT(!rd.IsSP()); |
| 2817 |
| 2818 for (unsigned i = 0; i < (rd.SizeInBits() / 16); i++) { |
| 2819 uint64_t imm16 = (imm >> (16 * i)) & 0xffffL; |
| 2820 movk(rd, imm16, 16 * i); |
| 2821 } |
| 2822 |
| 2823 ASSERT(SizeOfCodeGeneratedSince(&start) == |
| 2824 kMovInt64NInstrs * kInstructionSize); |
| 2825 } |
| 2826 |
| 2827 |
| 2828 void PatchingAssembler::PatchAdrFar(Instruction* target) { |
| 2829 // The code at the current instruction should be: |
| 2830 // adr rd, 0 |
| 2831 // nop (adr_far) |
| 2832 // nop (adr_far) |
| 2833 // nop (adr_far) |
| 2834 // movz scratch, 0 |
| 2835 // add rd, rd, scratch |
| 2836 |
| 2837 // Verify the expected code. |
| 2838 Instruction* expected_adr = InstructionAt(0); |
| 2839 CHECK(expected_adr->IsAdr() && (expected_adr->ImmPCRel() == 0)); |
| 2840 int rd_code = expected_adr->Rd(); |
| 2841 for (int i = 0; i < kAdrFarPatchableNNops; ++i) { |
| 2842 CHECK(InstructionAt((i + 1) * kInstructionSize)->IsNop(ADR_FAR_NOP)); |
| 2843 } |
| 2844 Instruction* expected_movz = |
| 2845 InstructionAt((kAdrFarPatchableNInstrs - 2) * kInstructionSize); |
| 2846 CHECK(expected_movz->IsMovz() && |
| 2847 (expected_movz->ImmMoveWide() == 0) && |
| 2848 (expected_movz->ShiftMoveWide() == 0)); |
| 2849 int scratch_code = expected_movz->Rd(); |
| 2850 Instruction* expected_add = |
| 2851 InstructionAt((kAdrFarPatchableNInstrs - 1) * kInstructionSize); |
| 2852 CHECK(expected_add->IsAddSubShifted() && |
| 2853 (expected_add->Mask(AddSubOpMask) == ADD) && |
| 2854 expected_add->SixtyFourBits() && |
| 2855 (expected_add->Rd() == rd_code) && (expected_add->Rn() == rd_code) && |
| 2856 (expected_add->Rm() == scratch_code) && |
| 2857 (static_cast<Shift>(expected_add->ShiftDP()) == LSL) && |
| 2858 (expected_add->ImmDPShift() == 0)); |
| 2859 |
| 2860 // Patch to load the correct address. |
| 2861 Label start; |
| 2862 bind(&start); |
| 2863 Register rd = Register::XRegFromCode(rd_code); |
| 2864 // If the target is in range, we only patch the adr. Otherwise we patch the |
| 2865 // nops with fixup instructions. |
| 2866 int target_offset = expected_adr->DistanceTo(target); |
| 2867 if (Instruction::IsValidPCRelOffset(target_offset)) { |
| 2868 adr(rd, target_offset); |
| 2869 for (int i = 0; i < kAdrFarPatchableNInstrs - 2; ++i) { |
| 2870 nop(ADR_FAR_NOP); |
| 2871 } |
| 2872 } else { |
| 2873 Register scratch = Register::XRegFromCode(scratch_code); |
| 2874 adr(rd, 0); |
| 2875 MovInt64(scratch, target_offset); |
| 2876 add(rd, rd, scratch); |
| 2877 } |
| 2878 } |
| 2879 |
| 2880 |
2811 } } // namespace v8::internal | 2881 } } // namespace v8::internal |
2812 | 2882 |
2813 #endif // V8_TARGET_ARCH_ARM64 | 2883 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |