Revision: 21932
Author:   [email protected]
Date:     Mon Jun 23 11:27:24 2014 UTC
Log:      [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.

[email protected]

Review URL: https://codereview.chromium.org/317653003
http://code.google.com/p/v8/source/detail?r=21932

Modified:
 /branches/bleeding_edge/src/arm/assembler-arm-inl.h
 /branches/bleeding_edge/src/arm/assembler-arm.cc
 /branches/bleeding_edge/src/arm/assembler-arm.h
 /branches/bleeding_edge/src/arm/constants-arm.h
 /branches/bleeding_edge/src/arm/full-codegen-arm.cc
 /branches/bleeding_edge/src/arm/macro-assembler-arm.cc
 /branches/bleeding_edge/src/objects.h

=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm-inl.h Tue Jun 3 08:12:43 2014 UTC +++ /branches/bleeding_edge/src/arm/assembler-arm-inl.h Mon Jun 23 11:27:24 2014 UTC
@@ -119,21 +119,14 @@
     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 @@
   // 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);
 }


@@ -426,42 +419,6 @@
   *reinterpret_cast<Instr*>(pc_) = x;
   pc_ += kInstrSize;
 }
-
-
-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) {
@@ -521,13 +478,65 @@
   instruction &= ~EncodeMovwImmediate(0xffff);
   return instruction | EncodeMovwImmediate(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 @@
     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.
   }
 }

=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.cc Fri Jun 13 10:50:11 2014 UTC +++ /branches/bleeding_edge/src/arm/assembler-arm.cc Mon Jun 23 11:27:24 2014 UTC
@@ -418,11 +418,11 @@
 // 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;
@@ -638,6 +638,15 @@
   reg.code_ = Instruction::RmValue(instr);
   return reg;
 }
+
+
+Instr Assembler::GetConsantPoolLoadPattern() {
+  if (FLAG_enable_ool_constant_pool) {
+    return kLdrPpImmedPattern;
+  } else {
+    return kLdrPCImmedPattern;
+  }
+}


 bool Assembler::IsPush(Instr instr) {
@@ -673,14 +682,14 @@
 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;
 }


@@ -696,6 +705,20 @@
   // vldr<cond> <Dd>, [pp +/- offset_10].
   return (instr & kVldrDPpMask) == kVldrDPpPattern;
 }
+
+
+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) {
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.h Fri Jun 20 08:40:11 2014 UTC +++ /branches/bleeding_edge/src/arm/assembler-arm.h Mon Jun 23 11:27:24 2014 UTC
@@ -672,32 +672,6 @@
   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 @@

// 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 @@
   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 @@
   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);
=======================================
--- /branches/bleeding_edge/src/arm/constants-arm.h Thu Jun 5 08:33:42 2014 UTC +++ /branches/bleeding_edge/src/arm/constants-arm.h Mon Jun 23 11:27:24 2014 UTC
@@ -403,64 +403,6 @@

 // Hints are not used on the arm.  Negating is trivial.
 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;


// -----------------------------------------------------------------------------
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Mon Jun 23 07:10:25 2014 UTC +++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Mon Jun 23 11:27:24 2014 UTC
@@ -4753,9 +4753,8 @@
                             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 @@

// 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 @@
     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);

=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Fri Jun 13 10:50:11 2014 UTC +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Mon Jun 23 11:27:24 2014 UTC
@@ -3630,15 +3630,9 @@
   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));
   }
=======================================
--- /branches/bleeding_edge/src/objects.h       Mon Jun 23 09:11:45 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Mon Jun 23 11:27:24 2014 UTC
@@ -1236,10 +1236,8 @@
"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, \

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to