Reviewers: ulan,

Description:
Fix ARM dissambler test problems with movw/movt.

[email protected]


Please review this at https://codereview.chromium.org/11198061/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/arm/assembler-arm.h
  M src/arm/assembler-arm.cc


Index: src/arm/assembler-arm.cc
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index cc3d5b11a323801f69ecdbc630b37a54a932c74e..9be62a404bd2935864095744d1d4fa8a985a937b 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -819,6 +819,17 @@ bool Operand::must_output_reloc_info(const Assembler* assembler) const {
 }


+static bool use_movw_movt(const Operand& x, const Assembler* assembler) {
+  if (Assembler::use_immediate_embedded_pointer_loads(assembler)) {
+    return true;
+  }
+  if (x.must_output_reloc_info(assembler)) {
+    return false;
+  }
+  return CpuFeatures::IsSupported(ARMv7);
+}
+
+
 bool Operand::is_single_instruction(const Assembler* assembler,
                                     Instr instr) const {
   if (rm_.is_valid()) return true;
@@ -829,23 +840,7 @@ bool Operand::is_single_instruction(const Assembler* assembler,
     // constant pool is required. For a mov instruction not setting the
     // condition code additional instruction conventions can be used.
     if ((instr & ~kCondMask) == 13*B21) {  // mov, S not set
-#ifdef USE_BLX
- // When using BLX, there are two things that must be true for the address - // load to be longer than a single instruction. First, immediate loads
-      // using movw/movt must be supported (and fast) on the target ARM
- // architecture. Second, the reloc mode must be something other than NONE,
-      // since NONE is a used whenever the constant pool cannot be used for
- // technical reasons, e.g. back-patching calls site in optimized code with
-      // a call to a lazy deopt routine.
-      return !Assembler::allow_immediate_constant_pool_loads(assembler) &&
-          rmode_ != RelocInfo::NONE;
-#else
- // It's not possible to use immediate loads to the pc to do a call, (the - // pc would be inconsistent half-way through the load), so loading the - // destination address without USE_BLX is always a single instruction of
-      // the form ldr pc, [pc + #xxx].
-      return true;
-#endif
+      return !use_movw_movt(*this, assembler);
     } else {
// If this is not a mov or mvn instruction there will always an additional
       // instructions - either mov or ldr. The mov might actually be two
@@ -866,26 +861,21 @@ void Assembler::move_32_bit_immediate(Condition cond,
                                       SBit s,
                                       const Operand& x) {
   if (rd.code() != pc.code() && s == LeaveCC) {
-    // Candidate for immediate load.
-    if (x.must_output_reloc_info(this)) {
-      if (!Assembler::allow_immediate_constant_pool_loads(this)) {
-        RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
-        ldr(rd, MemOperand(pc, 0), cond);
-        return;
+    if (use_movw_movt(x, this)) {
+      if (x.must_output_reloc_info(this)) {
+        RecordRelocInfo(x.rmode_, x.imm32_, DONT_USE_CONSTANT_POOL);
+        // Make sure the movw/movt doesn't get separated.
+        BlockConstPoolFor(2);
       }
-      RecordRelocInfo(x.rmode_, x.imm32_, DONT_USE_CONSTANT_POOL);
-      // Make sure the movw/movt doesn't get separated.
-      BlockConstPoolFor(2);
+      emit(cond | 0x30*B20 | rd.code()*B12 |
+           EncodeMovwImmediate(x.imm32_ & 0xffff));
+      movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond);
+      return;
     }
-
-    // Emit a real movw/movt pair.
-    emit(cond | 0x30*B20 | rd.code()*B12 |
-         EncodeMovwImmediate(x.imm32_ & 0xffff));
-    movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond);
-  } else {
-    RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
-    ldr(rd, MemOperand(pc, 0), cond);
   }
+
+  RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
+  ldr(rd, MemOperand(pc, 0), cond);
 }


@@ -910,14 +900,17 @@ void Assembler::addrmod1(Instr instr,
       if ((instr & ~kCondMask) == 13*B21) {  // mov, S not set
         move_32_bit_immediate(cond, rd, LeaveCC, x);
       } else {
- // If this is not a mov or mvn instruction we may still be able to avoid
-        // a constant pool entry by using mvn or movw.
-        if (!x.must_output_reloc_info(this) &&
-            (instr & kMovMvnMask) != kMovMvnPattern) {
-          mov(ip, x, LeaveCC, cond);
+        if ((instr & kMovMvnMask) == kMovMvnPattern) {
+          // Moves need to use a constant pool entry.
+          RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
+          ldr(ip, MemOperand(pc, 0), cond);
+        } else if (x.must_output_reloc_info(this)) {
+ // Otherwise, use most efficient form of fetching from constant pool.
+          move_32_bit_immediate(cond, ip, LeaveCC, x);
         } else {
-          move_32_bit_immediate(cond, ip,
-                                static_cast<SBit>(instr & (1 << 20)), x);
+ // If this is not a mov or mvn instruction we may still be able to
+          // avoid a constant pool entry by using mvn or movw.
+          mov(ip, x, LeaveCC, cond);
         }
         addrmod1(instr, rn, rd, Operand(ip));
       }
Index: src/arm/assembler-arm.h
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index bee35af15eed4fe96f2e0800cdb0b61945c259b4..dfcce6011414c363b40db8e96bda4b2208876478 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -1187,10 +1187,18 @@ class Assembler : public AssemblerBase {

   bool predictable_code_size() const { return predictable_code_size_; }

-  static bool allow_immediate_constant_pool_loads(
+  static bool use_immediate_embedded_pointer_loads(
       const Assembler* assembler) {
+#ifdef USE_BLX
     return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
         (assembler == NULL || !assembler->predictable_code_size());
+#else
+ // If not using BLX, all loads from the constant pool cannot be immediate,
+    // because the ldr pc, [pc + #xxxx] used for calls must be a single
+    // instruction and cannot be easily distinguished out of context from
+    // other loads that could use movw/movt.
+    return false;
+#endif
   }

   // Check the code size generated from label to here.


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to