Index: src/arm/macro-assembler-arm.cc |
=================================================================== |
--- src/arm/macro-assembler-arm.cc (revision 4189) |
+++ src/arm/macro-assembler-arm.cc (working copy) |
@@ -58,11 +58,6 @@ |
#endif |
-// Using blx may yield better code, so use it when required or when available |
-#if defined(USE_THUMB_INTERWORK) || defined(CAN_USE_ARMV5_INSTRUCTIONS) |
-#define USE_BLX 1 |
-#endif |
- |
// Using bx does not yield better code, so use it only when required |
#if defined(USE_THUMB_INTERWORK) |
#define USE_BX 1 |
@@ -117,16 +112,33 @@ |
void MacroAssembler::Call(intptr_t target, RelocInfo::Mode rmode, |
Condition cond) { |
+#if USE_BLX |
+ // On ARMv5 and after the recommended call sequence is: |
+ // ldr ip, [pc, #...] |
+ // blx ip |
+ |
+ // The two instructions (ldr and blx) could be separated by a literal |
+ // pool and the code would still work. The issue comes from the |
+ // patching code which expect the ldr to be just above the blx. |
+ BlockConstPoolFor(2); |
+ // Statement positions are expected to be recorded when the target |
+ // address is loaded. The mov method will automatically record |
+ // positions when pc is the target, since this is not the case here |
+ // we have to do it explicitly. |
+ WriteRecordedPositions(); |
+ |
+ mov(ip, Operand(target, rmode), LeaveCC, cond); |
+ blx(ip, cond); |
+ |
+ ASSERT(kCallTargetAddressOffset == 2 * kInstrSize); |
+#else |
// Set lr for return at current pc + 8. |
mov(lr, Operand(pc), LeaveCC, cond); |
// Emit a ldr<cond> pc, [pc + offset of target in constant pool]. |
mov(pc, Operand(target, rmode), LeaveCC, cond); |
- // If USE_BLX is defined, we could emit a 'mov ip, target', followed by a |
- // 'blx ip'; however, the code would not be shorter than the above sequence |
- // and the target address of the call would be referenced by the first |
- // instruction rather than the second one, which would make it harder to patch |
- // (two instructions before the return address, instead of one). |
+ |
ASSERT(kCallTargetAddressOffset == kInstrSize); |
+#endif |
} |