diff options
author | 2015-05-20 11:25:27 +0100 | |
---|---|---|
committer | 2015-05-20 11:25:27 +0100 | |
commit | d126ba19a2a3352fedbe43ed628ab60ccd401424 (patch) | |
tree | 79059b8060b33c3955cda9d5001dbf337e1b1f58 /compiler/utils/arm/assembler_thumb2.h | |
parent | 3e736b12d62ea539b71bd9e6ce953347c0f09a3e (diff) |
[Optimizing] Thumb2 assembler: use 16bits branches when we can.
We cannot relocate branches, but we can at least encode branches
on 16bits when the target is known.
Change-Id: Icb6116ed974fc97e03622ac80d914c2c06f4cba2
Diffstat (limited to 'compiler/utils/arm/assembler_thumb2.h')
-rw-r--r-- | compiler/utils/arm/assembler_thumb2.h | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/compiler/utils/arm/assembler_thumb2.h b/compiler/utils/arm/assembler_thumb2.h index 17eae8be0c..90d489fb02 100644 --- a/compiler/utils/arm/assembler_thumb2.h +++ b/compiler/utils/arm/assembler_thumb2.h @@ -31,8 +31,8 @@ namespace arm { class Thumb2Assembler FINAL : public ArmAssembler { public: - explicit Thumb2Assembler(bool force_32bit_branches = false) - : force_32bit_branches_(force_32bit_branches), + explicit Thumb2Assembler(bool can_relocate_branches = true) + : can_relocate_branches_(can_relocate_branches), force_32bit_(false), it_cond_index_(kNoItCondition), next_condition_(AL) { @@ -52,8 +52,8 @@ class Thumb2Assembler FINAL : public ArmAssembler { return force_32bit_; } - bool IsForced32BitBranches() const { - return force_32bit_branches_; + bool CanRelocateBranches() const { + return can_relocate_branches_; } void FinalizeInstructions(const MemoryRegion& region) OVERRIDE { @@ -439,8 +439,12 @@ class Thumb2Assembler FINAL : public ArmAssembler { void EmitShift(Register rd, Register rm, Shift shift, uint8_t amount, bool setcc = false); void EmitShift(Register rd, Register rn, Shift shift, Register rm, bool setcc = false); - bool force_32bit_branches_; // Force the assembler to use 32 bit branch instructions. - bool force_32bit_; // Force the assembler to use 32 bit thumb2 instructions. + // Whether the assembler can relocate branches. If false, unresolved branches will be + // emitted on 32bits. + bool can_relocate_branches_; + + // Force the assembler to use 32 bit thumb2 instructions. + bool force_32bit_; // IfThen conditions. Used to check that conditional instructions match the preceding IT. Condition it_conditions_[4]; @@ -556,12 +560,21 @@ class Thumb2Assembler FINAL : public ArmAssembler { // size of the branch to change return true. Otherwise return false. bool Resolve(uint32_t target) { target_ = target; - Size newsize = CalculateSize(); - if (size_ != newsize) { - size_ = newsize; - return true; + if (assembler_->CanRelocateBranches()) { + Size new_size = CalculateSize(); + if (size_ != new_size) { + size_ = new_size; + return true; + } + return false; + } else { + if (kIsDebugBuild) { + Size new_size = CalculateSize(); + // Check that the size has not increased. + DCHECK(!(new_size == k32Bit && size_ == k16Bit)); + } + return false; } - return false; } // Move a cbz/cbnz branch. This is always forward. @@ -577,6 +590,7 @@ class Thumb2Assembler FINAL : public ArmAssembler { // size of the branch instruction. It returns true if the branch // has changed size. bool Relocate(uint32_t oldlocation, int32_t delta) { + DCHECK(assembler_->CanRelocateBranches()); if (location_ > oldlocation) { location_ += delta; } @@ -589,9 +603,9 @@ class Thumb2Assembler FINAL : public ArmAssembler { } // Calculate the new size. - Size newsize = CalculateSize(); - if (size_ != newsize) { - size_ = newsize; + Size new_size = CalculateSize(); + if (size_ != new_size) { + size_ = new_size; return true; } return false; @@ -633,15 +647,13 @@ class Thumb2Assembler FINAL : public ArmAssembler { private: // Calculate the size of the branch instruction based on its type and offset. Size CalculateSize() const { - if (assembler_->IsForced32BitBranches()) { - return k32Bit; - } if (target_ == kUnresolved) { if (assembler_->IsForced32Bit() && (type_ == kUnconditional || type_ == kConditional)) { return k32Bit; } - return k16Bit; + return assembler_->CanRelocateBranches() ? k16Bit : k32Bit; } + // When the target is resolved, we know the best encoding for it. int32_t delta = target_ - location_ - 4; if (delta < 0) { delta = -delta; |