diff options
Diffstat (limited to 'compiler/utils')
| -rw-r--r-- | compiler/utils/arm/assembler_arm_vixl.cc | 22 | ||||
| -rw-r--r-- | compiler/utils/arm/assembler_arm_vixl.h | 61 |
2 files changed, 83 insertions, 0 deletions
diff --git a/compiler/utils/arm/assembler_arm_vixl.cc b/compiler/utils/arm/assembler_arm_vixl.cc index c35c39328c..1614d04a95 100644 --- a/compiler/utils/arm/assembler_arm_vixl.cc +++ b/compiler/utils/arm/assembler_arm_vixl.cc @@ -455,5 +455,27 @@ void ArmVIXLMacroAssembler::CompareAndBranchIfNonZero(vixl32::Register rn, B(ne, label); } +void ArmVIXLMacroAssembler::B(vixl32::Label* label) { + if (!label->IsBound()) { + // Try to use 16-bit T2 encoding of B instruction. + DCHECK(OutsideITBlock()); + AssemblerAccurateScope ass(this, + kMaxInstructionSizeInBytes, + CodeBufferCheckScope::kMaximumSize); + b(al, Narrow, label); + AddBranchLabel(label); + return; + } + MacroAssembler::B(label); +} + +void ArmVIXLMacroAssembler::B(vixl32::Condition cond, vixl32::Label* label) { + // To further reduce the Bcc encoding size and use 16-bit T1 encoding, + // we can provide a hint to this function: i.e. far_target=false. + // By default this function uses 'EncodingSizeType::Best' which generates 32-bit T3 encoding. + MacroAssembler::B(cond, label); +} + + } // namespace arm } // namespace art diff --git a/compiler/utils/arm/assembler_arm_vixl.h b/compiler/utils/arm/assembler_arm_vixl.h index b4a4abc87e..5ee5fa5d5e 100644 --- a/compiler/utils/arm/assembler_arm_vixl.h +++ b/compiler/utils/arm/assembler_arm_vixl.h @@ -54,6 +54,67 @@ class ArmVIXLMacroAssembler FINAL : public vixl32::MacroAssembler { void CompareAndBranchIfNonZero(vixl32::Register rn, vixl32::Label* label, bool is_far_target = true); + + // In T32 some of the instructions (add, mov, etc) outside an IT block + // have only 32-bit encodings. But there are 16-bit flag setting + // versions of these instructions (adds, movs, etc). In most of the + // cases in ART we don't care if the instructions keep flags or not; + // thus we can benefit from smaller code size. + // VIXL will never generate flag setting versions (for example, adds + // for Add macro instruction) unless vixl32::DontCare option is + // explicitly specified. That's why we introduce wrappers to use + // DontCare option by default. +#define WITH_FLAGS_DONT_CARE_RD_RN_OP(func_name) \ + void (func_name)(vixl32::Register rd, vixl32::Register rn, const vixl32::Operand& operand) { \ + MacroAssembler::func_name(vixl32::DontCare, rd, rn, operand); \ + } \ + using MacroAssembler::func_name + + WITH_FLAGS_DONT_CARE_RD_RN_OP(Add); + WITH_FLAGS_DONT_CARE_RD_RN_OP(Adc); + WITH_FLAGS_DONT_CARE_RD_RN_OP(Sub); + WITH_FLAGS_DONT_CARE_RD_RN_OP(Sbc); + WITH_FLAGS_DONT_CARE_RD_RN_OP(Rsb); + WITH_FLAGS_DONT_CARE_RD_RN_OP(Rsc); + + WITH_FLAGS_DONT_CARE_RD_RN_OP(Eor); + WITH_FLAGS_DONT_CARE_RD_RN_OP(Orr); + WITH_FLAGS_DONT_CARE_RD_RN_OP(Orn); + WITH_FLAGS_DONT_CARE_RD_RN_OP(And); + WITH_FLAGS_DONT_CARE_RD_RN_OP(Bic); + + WITH_FLAGS_DONT_CARE_RD_RN_OP(Asr); + WITH_FLAGS_DONT_CARE_RD_RN_OP(Lsr); + WITH_FLAGS_DONT_CARE_RD_RN_OP(Lsl); + WITH_FLAGS_DONT_CARE_RD_RN_OP(Ror); + +#undef WITH_FLAGS_DONT_CARE_RD_RN_OP + +#define WITH_FLAGS_DONT_CARE_RD_OP(func_name) \ + void (func_name)(vixl32::Register rd, const vixl32::Operand& operand) { \ + MacroAssembler::func_name(vixl32::DontCare, rd, operand); \ + } \ + using MacroAssembler::func_name + + WITH_FLAGS_DONT_CARE_RD_OP(Mvn); + WITH_FLAGS_DONT_CARE_RD_OP(Mov); + +#undef WITH_FLAGS_DONT_CARE_RD_OP + + // The following two functions don't fall into above categories. Overload them separately. + void Rrx(vixl32::Register rd, vixl32::Register rn) { + MacroAssembler::Rrx(vixl32::DontCare, rd, rn); + } + using MacroAssembler::Rrx; + + void Mul(vixl32::Register rd, vixl32::Register rn, vixl32::Register rm) { + MacroAssembler::Mul(vixl32::DontCare, rd, rn, rm); + } + using MacroAssembler::Mul; + + // 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); }; class ArmVIXLAssembler FINAL : public Assembler { |