From: rmcilroy@chromium.org Date: Mon, 23 Jun 2014 11:27:24 +0000 (+0000) Subject: [Arm] Various cleanups to the Arm assembler backend. X-Git-Tag: upstream/4.7.83~8606 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1b080a76c1b71e1cf78a2ce9055f75ab5b961cce;p=platform%2Fupstream%2Fv8.git [Arm] Various cleanups to the Arm assembler backend. A couple of cleanups to the Arm backend to enable support of extended OOL constant pools in a following CL. - Remove instruction pattern extern const's and replace their use with IsXXX() functions. - Do calculation of the target address of a load from constant pool in one place. - A couple of other small cleanups. R=ulan@chromium.org Review URL: https://codereview.chromium.org/317653003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21932 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/assembler-arm-inl.h b/src/arm/assembler-arm-inl.h index d09e700..0ca2314 100644 --- a/src/arm/assembler-arm-inl.h +++ b/src/arm/assembler-arm-inl.h @@ -119,21 +119,14 @@ Address RelocInfo::target_address_address() { return reinterpret_cast
(pc_); } else { ASSERT(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_))); - return Assembler::target_pointer_address_at(pc_); + return constant_pool_entry_address(); } } Address RelocInfo::constant_pool_entry_address() { ASSERT(IsInConstantPool()); - if (FLAG_enable_ool_constant_pool) { - ASSERT(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc_))); - return Assembler::target_constant_pool_address_at(pc_, - host_->constant_pool()); - } else { - ASSERT(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_))); - return Assembler::target_pointer_address_at(pc_); - } + return Assembler::constant_pool_entry_address(pc_, host_->constant_pool()); } @@ -314,8 +307,8 @@ bool RelocInfo::IsPatchedReturnSequence() { // A patched return sequence is: // ldr ip, [pc, #0] // blx ip - return ((current_instr & kLdrPCMask) == kLdrPCPattern) - && ((next_instr & kBlxRegMask) == kBlxRegPattern); + return Assembler::IsLdrPcImmediateOffset(current_instr) && + Assembler::IsBlxReg(next_instr); } @@ -428,42 +421,6 @@ void Assembler::emit(Instr x) { } -Address Assembler::target_pointer_address_at(Address pc) { - Instr instr = Memory::int32_at(pc); - return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta; -} - - -Address Assembler::target_constant_pool_address_at( - Address pc, ConstantPoolArray* constant_pool) { - ASSERT(constant_pool != NULL); - ASSERT(IsLdrPpImmediateOffset(Memory::int32_at(pc))); - Instr instr = Memory::int32_at(pc); - return reinterpret_cast
(constant_pool) + - GetLdrRegisterImmediateOffset(instr); -} - - -Address Assembler::target_address_at(Address pc, - ConstantPoolArray* constant_pool) { - if (IsMovW(Memory::int32_at(pc))) { - ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize))); - Instruction* instr = Instruction::At(pc); - Instruction* next_instr = Instruction::At(pc + kInstrSize); - return reinterpret_cast
( - (next_instr->ImmedMovwMovtValue() << 16) | - instr->ImmedMovwMovtValue()); - } else if (FLAG_enable_ool_constant_pool) { - ASSERT(IsLdrPpImmediateOffset(Memory::int32_at(pc))); - return Memory::Address_at( - target_constant_pool_address_at(pc, constant_pool)); - } else { - ASSERT(IsLdrPcImmediateOffset(Memory::int32_at(pc))); - return Memory::Address_at(target_pointer_address_at(pc)); - } -} - - Address Assembler::target_address_from_return_address(Address pc) { // Returns the address of the call target from the return address that will // be returned to after a call. @@ -523,11 +480,63 @@ static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate) { } +static bool IsConstantPoolLoad(Address pc) { + return !Assembler::IsMovW(Memory::int32_at(pc)); +} + + +Address Assembler::constant_pool_entry_address( + Address pc, ConstantPoolArray* constant_pool) { + if (FLAG_enable_ool_constant_pool) { + ASSERT(constant_pool != NULL); + ASSERT(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc))); + return reinterpret_cast
(constant_pool) + + GetLdrRegisterImmediateOffset(Memory::int32_at(pc)); + } else { + ASSERT(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc))); + Instr instr = Memory::int32_at(pc); + return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta; + } +} + + +Address Assembler::target_address_at(Address pc, + ConstantPoolArray* constant_pool) { + if (IsConstantPoolLoad(pc)) { + // This is a constant pool lookup. Return the value in the constant pool. + return Memory::Address_at(constant_pool_entry_address(pc, constant_pool)); + } else { + // This is an movw_movt immediate load. Return the immediate. + ASSERT(IsMovW(Memory::int32_at(pc)) && + IsMovT(Memory::int32_at(pc + kInstrSize))); + Instruction* movw_instr = Instruction::At(pc); + Instruction* movt_instr = Instruction::At(pc + kInstrSize); + return reinterpret_cast
( + (movt_instr->ImmedMovwMovtValue() << 16) | + movw_instr->ImmedMovwMovtValue()); + } +} + + void Assembler::set_target_address_at(Address pc, ConstantPoolArray* constant_pool, Address target, ICacheFlushMode icache_flush_mode) { - if (IsMovW(Memory::int32_at(pc))) { + if (IsConstantPoolLoad(pc)) { + // This is a constant pool lookup. Update the entry in the constant pool. + Memory::Address_at(constant_pool_entry_address(pc, constant_pool)) = target; + // Intuitively, we would think it is necessary to always flush the + // instruction cache after patching a target address in the code as follows: + // CPU::FlushICache(pc, sizeof(target)); + // However, on ARM, no instruction is actually patched in the case + // of embedded constants of the form: + // ldr ip, [pp, #...] + // since the instruction accessing this address in the constant pool remains + // unchanged. + } else { + // This is an movw_movt immediate load. Patch the immediate embedded in the + // instructions. + ASSERT(IsMovW(Memory::int32_at(pc))); ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize))); uint32_t* instr_ptr = reinterpret_cast(pc); uint32_t immediate = reinterpret_cast(target); @@ -538,21 +547,6 @@ void Assembler::set_target_address_at(Address pc, if (icache_flush_mode != SKIP_ICACHE_FLUSH) { CPU::FlushICache(pc, 2 * kInstrSize); } - } else if (FLAG_enable_ool_constant_pool) { - ASSERT(IsLdrPpImmediateOffset(Memory::int32_at(pc))); - Memory::Address_at( - target_constant_pool_address_at(pc, constant_pool)) = target; - } else { - ASSERT(IsLdrPcImmediateOffset(Memory::int32_at(pc))); - Memory::Address_at(target_pointer_address_at(pc)) = target; - // Intuitively, we would think it is necessary to always flush the - // instruction cache after patching a target address in the code as follows: - // CPU::FlushICache(pc, sizeof(target)); - // However, on ARM, no instruction is actually patched in the case - // of embedded constants of the form: - // ldr ip, [pc, #...] - // since the instruction accessing this address in the constant pool remains - // unchanged. } } diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc index 68738a7..c3afeaa 100644 --- a/src/arm/assembler-arm.cc +++ b/src/arm/assembler-arm.cc @@ -418,11 +418,11 @@ const Instr kPopRegPattern = // mov lr, pc const Instr kMovLrPc = al | MOV | kRegister_pc_Code | kRegister_lr_Code * B12; // ldr rd, [pc, #offset] -const Instr kLdrPCMask = 15 * B24 | 7 * B20 | 15 * B16; -const Instr kLdrPCPattern = 5 * B24 | L | kRegister_pc_Code * B16; +const Instr kLdrPCImmedMask = 15 * B24 | 7 * B20 | 15 * B16; +const Instr kLdrPCImmedPattern = 5 * B24 | L | kRegister_pc_Code * B16; // ldr rd, [pp, #offset] -const Instr kLdrPpMask = 15 * B24 | 7 * B20 | 15 * B16; -const Instr kLdrPpPattern = 5 * B24 | L | kRegister_r8_Code * B16; +const Instr kLdrPpImmedMask = 15 * B24 | 7 * B20 | 15 * B16; +const Instr kLdrPpImmedPattern = 5 * B24 | L | kRegister_r8_Code * B16; // vldr dd, [pc, #offset] const Instr kVldrDPCMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8; const Instr kVldrDPCPattern = 13 * B24 | L | kRegister_pc_Code * B16 | 11 * B8; @@ -640,6 +640,15 @@ Register Assembler::GetRm(Instr instr) { } +Instr Assembler::GetConsantPoolLoadPattern() { + if (FLAG_enable_ool_constant_pool) { + return kLdrPpImmedPattern; + } else { + return kLdrPCImmedPattern; + } +} + + bool Assembler::IsPush(Instr instr) { return ((instr & ~kRdMask) == kPushRegPattern); } @@ -673,14 +682,14 @@ bool Assembler::IsLdrRegFpNegOffset(Instr instr) { bool Assembler::IsLdrPcImmediateOffset(Instr instr) { // Check the instruction is indeed a // ldr , [pc +/- offset_12]. - return (instr & kLdrPCMask) == kLdrPCPattern; + return (instr & kLdrPCImmedMask) == kLdrPCImmedPattern; } bool Assembler::IsLdrPpImmediateOffset(Instr instr) { // Check the instruction is indeed a // ldr , [pp +/- offset_12]. - return (instr & kLdrPpMask) == kLdrPpPattern; + return (instr & kLdrPpImmedMask) == kLdrPpImmedPattern; } @@ -698,6 +707,20 @@ bool Assembler::IsVldrDPpImmediateOffset(Instr instr) { } +bool Assembler::IsBlxReg(Instr instr) { + // Check the instruction is indeed a + // blxcc + return (instr & kBlxRegMask) == kBlxRegPattern; +} + + +bool Assembler::IsBlxIp(Instr instr) { + // Check the instruction is indeed a + // blx ip + return instr == kBlxIp; +} + + bool Assembler::IsTstImmediate(Instr instr) { return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask)) == (I | TST | S); diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h index be06591..3d91628 100644 --- a/src/arm/assembler-arm.h +++ b/src/arm/assembler-arm.h @@ -672,32 +672,6 @@ class ConstantPoolBuilder BASE_EMBEDDED { int count_of_32bit_; }; - -extern const Instr kMovLrPc; -extern const Instr kLdrPCMask; -extern const Instr kLdrPCPattern; -extern const Instr kLdrPpMask; -extern const Instr kLdrPpPattern; -extern const Instr kBlxRegMask; -extern const Instr kBlxRegPattern; -extern const Instr kBlxIp; - -extern const Instr kMovMvnMask; -extern const Instr kMovMvnPattern; -extern const Instr kMovMvnFlip; - -extern const Instr kMovLeaveCCMask; -extern const Instr kMovLeaveCCPattern; -extern const Instr kMovwMask; -extern const Instr kMovwPattern; -extern const Instr kMovwLeaveCCFlip; - -extern const Instr kCmpCmnMask; -extern const Instr kCmpCmnPattern; -extern const Instr kCmpCmnFlip; -extern const Instr kAddSubFlip; -extern const Instr kAndBicFlip; - struct VmovIndex { unsigned char index; }; @@ -751,11 +725,7 @@ class Assembler : public AssemblerBase { // Return the address in the constant pool of the code target address used by // the branch/call instruction at pc, or the object in a mov. - INLINE(static Address target_pointer_address_at(Address pc)); - - // Return the address in the constant pool of the code target address used by - // the branch/call instruction at pc, or the object in a mov. - INLINE(static Address target_constant_pool_address_at( + INLINE(static Address constant_pool_entry_address( Address pc, ConstantPoolArray* constant_pool)); // Read/Modify the code target address in the branch/call instruction at pc. @@ -1390,6 +1360,7 @@ class Assembler : public AssemblerBase { static int GetBranchOffset(Instr instr); static bool IsLdrRegisterImmediate(Instr instr); static bool IsVldrDRegisterImmediate(Instr instr); + static Instr GetConsantPoolLoadPattern(); static bool IsLdrPpImmediateOffset(Instr instr); static bool IsVldrDPpImmediateOffset(Instr instr); static int GetLdrRegisterImmediateOffset(Instr instr); @@ -1411,6 +1382,8 @@ class Assembler : public AssemblerBase { static bool IsLdrRegFpNegOffset(Instr instr); static bool IsLdrPcImmediateOffset(Instr instr); static bool IsVldrDPcImmediateOffset(Instr instr); + static bool IsBlxReg(Instr instr); + static bool IsBlxIp(Instr instr); static bool IsTstImmediate(Instr instr); static bool IsCmpRegister(Instr instr); static bool IsCmpImmediate(Instr instr); diff --git a/src/arm/constants-arm.h b/src/arm/constants-arm.h index 0847ea1..6a2d82f 100644 --- a/src/arm/constants-arm.h +++ b/src/arm/constants-arm.h @@ -406,64 +406,6 @@ inline Hint NegateHint(Hint ignored) { return no_hint; } // ----------------------------------------------------------------------------- -// Specific instructions, constants, and masks. -// These constants are declared in assembler-arm.cc, as they use named registers -// and other constants. - - -// add(sp, sp, 4) instruction (aka Pop()) -extern const Instr kPopInstruction; - -// str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r)) -// register r is not encoded. -extern const Instr kPushRegPattern; - -// ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r)) -// register r is not encoded. -extern const Instr kPopRegPattern; - -// mov lr, pc -extern const Instr kMovLrPc; -// ldr rd, [pc, #offset] -extern const Instr kLdrPCMask; -extern const Instr kLdrPCPattern; -// vldr dd, [pc, #offset] -extern const Instr kVldrDPCMask; -extern const Instr kVldrDPCPattern; -// blxcc rm -extern const Instr kBlxRegMask; - -extern const Instr kBlxRegPattern; - -extern const Instr kMovMvnMask; -extern const Instr kMovMvnPattern; -extern const Instr kMovMvnFlip; -extern const Instr kMovLeaveCCMask; -extern const Instr kMovLeaveCCPattern; -extern const Instr kMovwMask; -extern const Instr kMovwPattern; -extern const Instr kMovwLeaveCCFlip; -extern const Instr kCmpCmnMask; -extern const Instr kCmpCmnPattern; -extern const Instr kCmpCmnFlip; -extern const Instr kAddSubFlip; -extern const Instr kAndBicFlip; - -// A mask for the Rd register for push, pop, ldr, str instructions. -extern const Instr kLdrRegFpOffsetPattern; - -extern const Instr kStrRegFpOffsetPattern; - -extern const Instr kLdrRegFpNegOffsetPattern; - -extern const Instr kStrRegFpNegOffsetPattern; - -extern const Instr kLdrStrInstrTypeMask; -extern const Instr kLdrStrInstrArgumentMask; -extern const Instr kLdrStrOffsetMask; - - -// ----------------------------------------------------------------------------- // Instruction abstraction. // The class Instruction enables access to individual fields defined in the ARM diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index cce8c05..f0fafa5 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -4753,9 +4753,8 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code, Address pc, BackEdgeState target_state, Code* replacement_code) { - static const int kInstrSize = Assembler::kInstrSize; Address pc_immediate_load_address = GetInterruptImmediateLoadAddress(pc); - Address branch_address = pc_immediate_load_address - kInstrSize; + Address branch_address = pc_immediate_load_address - Assembler::kInstrSize; CodePatcher patcher(branch_address, 1); switch (target_state) { case INTERRUPT: @@ -4770,7 +4769,7 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code, // Calculate branch offet to the ok-label - this is the difference between // the branch address and |pc| (which points at ) plus one instr. - int branch_offset = pc + kInstrSize - branch_address; + int branch_offset = pc + Assembler::kInstrSize - branch_address; patcher.masm()->b(branch_offset, pl); break; } @@ -4800,11 +4799,10 @@ BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState( Isolate* isolate, Code* unoptimized_code, Address pc) { - static const int kInstrSize = Assembler::kInstrSize; - ASSERT(Memory::int32_at(pc - kInstrSize) == kBlxIp); + ASSERT(Assembler::IsBlxIp(Memory::int32_at(pc - Assembler::kInstrSize))); Address pc_immediate_load_address = GetInterruptImmediateLoadAddress(pc); - Address branch_address = pc_immediate_load_address - kInstrSize; + Address branch_address = pc_immediate_load_address - Assembler::kInstrSize; Address interrupt_address = Assembler::target_address_at( pc_immediate_load_address, unoptimized_code); diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc index c34a7f7..4b67225 100644 --- a/src/arm/macro-assembler-arm.cc +++ b/src/arm/macro-assembler-arm.cc @@ -3630,15 +3630,9 @@ void MacroAssembler::GetRelocatedValueLocation(Register ldr_location, ldr(result, MemOperand(ldr_location)); if (emit_debug_code()) { // Check that the instruction is a ldr reg, [ + offset] . - if (FLAG_enable_ool_constant_pool) { - and_(result, result, Operand(kLdrPpPattern)); - cmp(result, Operand(kLdrPpPattern)); - Check(eq, kTheInstructionToPatchShouldBeALoadFromPp); - } else { - and_(result, result, Operand(kLdrPCPattern)); - cmp(result, Operand(kLdrPCPattern)); - Check(eq, kTheInstructionToPatchShouldBeALoadFromPc); - } + and_(result, result, Operand(GetConsantPoolLoadPattern())); + cmp(result, Operand(GetConsantPoolLoadPattern())); + Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool); // Result was clobbered. Restore it. ldr(result, MemOperand(ldr_location)); } diff --git a/src/objects.h b/src/objects.h index 22e0083..df57f6e 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1236,10 +1236,8 @@ template inline bool Is(Object* obj); "The current stack pointer is below csp") \ V(kTheInstructionShouldBeALui, "The instruction should be a lui") \ V(kTheInstructionShouldBeAnOri, "The instruction should be an ori") \ - V(kTheInstructionToPatchShouldBeALoadFromPc, \ - "The instruction to patch should be a load from pc") \ - V(kTheInstructionToPatchShouldBeALoadFromPp, \ - "The instruction to patch should be a load from pp") \ + V(kTheInstructionToPatchShouldBeALoadFromConstantPool, \ + "The instruction to patch should be a load from the constant pool") \ V(kTheInstructionToPatchShouldBeAnLdrLiteral, \ "The instruction to patch should be a ldr literal") \ V(kTheInstructionToPatchShouldBeALui, \