Chromium Code Reviews| 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 3070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3081 } | 3081 } |
| 3082 | 3082 |
| 3083 | 3083 |
| 3084 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { | 3084 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { |
| 3085 // No out-of-line constant pool support. | 3085 // No out-of-line constant pool support. |
| 3086 ASSERT(!FLAG_enable_ool_constant_pool); | 3086 ASSERT(!FLAG_enable_ool_constant_pool); |
| 3087 return; | 3087 return; |
| 3088 } | 3088 } |
| 3089 | 3089 |
| 3090 | 3090 |
| 3091 void PatchingAssembler::MovInt64(const Register& rd, int64_t imm) { | 3091 void PatchingAssembler::PatchAdrFar(ptrdiff_t target_offset) { |
| 3092 Label start; | |
| 3093 bind(&start); | |
| 3094 | |
| 3095 ASSERT(rd.Is64Bits()); | |
| 3096 ASSERT(!rd.IsSP()); | |
| 3097 | |
| 3098 for (unsigned i = 0; i < (rd.SizeInBits() / 16); i++) { | |
| 3099 uint64_t imm16 = (imm >> (16 * i)) & 0xffffL; | |
| 3100 movk(rd, imm16, 16 * i); | |
| 3101 } | |
| 3102 | |
| 3103 ASSERT(SizeOfCodeGeneratedSince(&start) == | |
| 3104 kMovInt64NInstrs * kInstructionSize); | |
| 3105 } | |
| 3106 | |
| 3107 | |
| 3108 void PatchingAssembler::PatchAdrFar(Instruction* target) { | |
| 3109 // The code at the current instruction should be: | 3092 // The code at the current instruction should be: |
| 3110 // adr rd, 0 | 3093 // adr rd, 0 |
| 3111 // nop (adr_far) | 3094 // nop (adr_far) |
| 3112 // nop (adr_far) | 3095 // nop (adr_far) |
| 3113 // nop (adr_far) | |
| 3114 // movz scratch, 0 | 3096 // movz scratch, 0 |
| 3115 // add rd, rd, scratch | |
|
ulan
2014/07/03 10:36:20
Why not remove (nop, nop) instead of (nop, add)?
vincent.belliard
2014/07/03 10:46:06
The add has a cost (the processor doesn't know tha
ulan
2014/07/03 11:01:48
ok, thanks.
| |
| 3116 | 3097 |
| 3117 // Verify the expected code. | 3098 // Verify the expected code. |
| 3118 Instruction* expected_adr = InstructionAt(0); | 3099 Instruction* expected_adr = InstructionAt(0); |
| 3119 CHECK(expected_adr->IsAdr() && (expected_adr->ImmPCRel() == 0)); | 3100 CHECK(expected_adr->IsAdr() && (expected_adr->ImmPCRel() == 0)); |
| 3120 int rd_code = expected_adr->Rd(); | 3101 int rd_code = expected_adr->Rd(); |
| 3121 for (int i = 0; i < kAdrFarPatchableNNops; ++i) { | 3102 for (int i = 0; i < kAdrFarPatchableNNops; ++i) { |
| 3122 CHECK(InstructionAt((i + 1) * kInstructionSize)->IsNop(ADR_FAR_NOP)); | 3103 CHECK(InstructionAt((i + 1) * kInstructionSize)->IsNop(ADR_FAR_NOP)); |
| 3123 } | 3104 } |
| 3124 Instruction* expected_movz = | 3105 Instruction* expected_movz = |
| 3125 InstructionAt((kAdrFarPatchableNInstrs - 2) * kInstructionSize); | 3106 InstructionAt((kAdrFarPatchableNInstrs - 1) * kInstructionSize); |
| 3126 CHECK(expected_movz->IsMovz() && | 3107 CHECK(expected_movz->IsMovz() && |
| 3127 (expected_movz->ImmMoveWide() == 0) && | 3108 (expected_movz->ImmMoveWide() == 0) && |
| 3128 (expected_movz->ShiftMoveWide() == 0)); | 3109 (expected_movz->ShiftMoveWide() == 0)); |
| 3129 int scratch_code = expected_movz->Rd(); | 3110 int scratch_code = expected_movz->Rd(); |
| 3130 Instruction* expected_add = | |
| 3131 InstructionAt((kAdrFarPatchableNInstrs - 1) * kInstructionSize); | |
| 3132 CHECK(expected_add->IsAddSubShifted() && | |
| 3133 (expected_add->Mask(AddSubOpMask) == ADD) && | |
| 3134 expected_add->SixtyFourBits() && | |
| 3135 (expected_add->Rd() == rd_code) && (expected_add->Rn() == rd_code) && | |
| 3136 (expected_add->Rm() == scratch_code) && | |
| 3137 (static_cast<Shift>(expected_add->ShiftDP()) == LSL) && | |
| 3138 (expected_add->ImmDPShift() == 0)); | |
| 3139 | 3111 |
| 3140 // Patch to load the correct address. | 3112 // Patch to load the correct address. |
| 3141 Label start; | |
| 3142 bind(&start); | |
| 3143 Register rd = Register::XRegFromCode(rd_code); | 3113 Register rd = Register::XRegFromCode(rd_code); |
| 3144 // If the target is in range, we only patch the adr. Otherwise we patch the | 3114 Register scratch = Register::XRegFromCode(scratch_code); |
| 3145 // nops with fixup instructions. | 3115 // Addresses are only 48 bits. |
| 3146 int target_offset = expected_adr->DistanceTo(target); | 3116 adr(rd, target_offset & 0xFFFF); |
| 3147 if (Instruction::IsValidPCRelOffset(target_offset)) { | 3117 movz(scratch, (target_offset >> 16) & 0xFFFF, 16); |
| 3148 adr(rd, target_offset); | 3118 movk(scratch, (target_offset >> 32) & 0xFFFF, 32); |
| 3149 for (int i = 0; i < kAdrFarPatchableNInstrs - 2; ++i) { | 3119 ASSERT((target_offset >> 48) == 0); |
| 3150 nop(ADR_FAR_NOP); | 3120 add(rd, rd, scratch); |
| 3151 } | |
| 3152 } else { | |
| 3153 Register scratch = Register::XRegFromCode(scratch_code); | |
| 3154 adr(rd, 0); | |
| 3155 MovInt64(scratch, target_offset); | |
| 3156 add(rd, rd, scratch); | |
| 3157 } | |
| 3158 } | 3121 } |
| 3159 | 3122 |
| 3160 | 3123 |
| 3161 } } // namespace v8::internal | 3124 } } // namespace v8::internal |
| 3162 | 3125 |
| 3163 #endif // V8_TARGET_ARCH_ARM64 | 3126 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |