Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: src/arm64/assembler-arm64.cc

Issue 363293004: ARM64: improve Adr patching (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm64/assembler-arm64.h ('k') | src/arm64/instructions-arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
OLDNEW
« no previous file with comments | « src/arm64/assembler-arm64.h ('k') | src/arm64/instructions-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698