ARM: VIXL32: Use 16-bit encoding for B(cond,...) where possible.
If conditional branch's target is known to be not far from branch
(within the range of 254 bytes), 16-bit encoding can be used.
However, we can't assume this by default for branches to a basic
block or a slow path; if we do and fail the range requirement,
veneer pool will be emitted.
Test: ART_USE_VIXL_ARM_BACKEND=true m test-art-host
Test: ART_USE_VIXL_ARM_BACKEND=true m test-art-target
Change-Id: I2fbe6d1a43bc2d1b54472c2c3fe05a575e5634f2
diff --git a/compiler/utils/arm/assembler_arm_vixl.h b/compiler/utils/arm/assembler_arm_vixl.h
index 5661249..3cf6a2e 100644
--- a/compiler/utils/arm/assembler_arm_vixl.h
+++ b/compiler/utils/arm/assembler_arm_vixl.h
@@ -114,7 +114,7 @@
// TODO: Remove when MacroAssembler::Add(FlagsUpdate, Condition, Register, Register, Operand)
// makes the right decision about 16-bit encodings.
void Add(vixl32::Register rd, vixl32::Register rn, const vixl32::Operand& operand) {
- if (rd.Is(rn)) {
+ if (rd.Is(rn) && operand.IsPlainRegister()) {
MacroAssembler::Add(rd, rn, operand);
} else {
MacroAssembler::Add(vixl32::DontCare, rd, rn, operand);
@@ -124,7 +124,10 @@
// These interfaces try to use 16-bit T2 encoding of B instruction.
void B(vixl32::Label* label);
- void B(vixl32::Condition cond, vixl32::Label* label);
+ // For B(label), we always try to use Narrow encoding, because 16-bit T2 encoding supports
+ // jumping within 2KB range. For B(cond, label), because the supported branch range is 256
+ // bytes; we use the far_target hint to try to use 16-bit T1 encoding for short range jumps.
+ void B(vixl32::Condition cond, vixl32::Label* label, bool is_far_target = true);
};
class ArmVIXLAssembler FINAL : public Assembler {