[Arm] Various cleanups to the Arm assembler backend.
authorrmcilroy@chromium.org <rmcilroy@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 23 Jun 2014 11:27:24 +0000 (11:27 +0000)
committerrmcilroy@chromium.org <rmcilroy@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 23 Jun 2014 11:27:24 +0000 (11:27 +0000)
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

src/arm/assembler-arm-inl.h
src/arm/assembler-arm.cc
src/arm/assembler-arm.h
src/arm/constants-arm.h
src/arm/full-codegen-arm.cc
src/arm/macro-assembler-arm.cc
src/objects.h

index d09e700..0ca2314 100644 (file)
@@ -119,21 +119,14 @@ Address RelocInfo::target_address_address() {
     return reinterpret_cast<Address>(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<Address>(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<Address>(
-        (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<Address>(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<Address>(
+        (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<uint32_t*>(pc);
     uint32_t immediate = reinterpret_cast<uint32_t>(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.
   }
 }
 
index 68738a7..c3afeaa 100644 (file)
@@ -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<cond> <Rd>, [pc +/- offset_12].
-  return (instr & kLdrPCMask) == kLdrPCPattern;
+  return (instr & kLdrPCImmedMask) == kLdrPCImmedPattern;
 }
 
 
 bool Assembler::IsLdrPpImmediateOffset(Instr instr) {
   // Check the instruction is indeed a
   // ldr<cond> <Rd>, [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 <Rm>
+  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);
index be06591..3d91628 100644 (file)
@@ -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);
index 0847ea1..6a2d82f 100644 (file)
@@ -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
index cce8c05..f0fafa5 100644 (file)
@@ -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 <blx ip>) 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);
 
index c34a7f7..4b67225 100644 (file)
@@ -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, [<pc or pp> + 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));
   }
index 22e0083..df57f6e 100644 (file)
@@ -1236,10 +1236,8 @@ template <class C> 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,                                       \