diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 40 | ||||
-rw-r--r-- | compiler/optimizing/common_arm.h | 8 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier_arm.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/scheduler_arm.cc | 1 |
4 files changed, 32 insertions, 21 deletions
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index b9d4700511..430cdde1f7 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -8269,19 +8269,41 @@ void InstructionCodeGeneratorARMVIXL::VisitDataProcWithShifterOp( const HDataProcWithShifterOp::OpKind op_kind = instruction->GetOpKind(); if (instruction->GetType() == Primitive::kPrimInt) { - DCHECK(!HDataProcWithShifterOp::IsExtensionOp(op_kind)); - + const vixl32::Register first = InputRegisterAt(instruction, 0); + const vixl32::Register output = OutputRegister(instruction); const vixl32::Register second = instruction->InputAt(1)->GetType() == Primitive::kPrimLong ? LowRegisterFrom(locations->InAt(1)) : InputRegisterAt(instruction, 1); - GenerateDataProcInstruction(kind, - OutputRegister(instruction), - InputRegisterAt(instruction, 0), - Operand(second, - ShiftFromOpKind(op_kind), - instruction->GetShiftAmount()), - codegen_); + if (HDataProcWithShifterOp::IsExtensionOp(op_kind)) { + DCHECK_EQ(kind, HInstruction::kAdd); + + switch (op_kind) { + case HDataProcWithShifterOp::kUXTB: + __ Uxtab(output, first, second); + break; + case HDataProcWithShifterOp::kUXTH: + __ Uxtah(output, first, second); + break; + case HDataProcWithShifterOp::kSXTB: + __ Sxtab(output, first, second); + break; + case HDataProcWithShifterOp::kSXTH: + __ Sxtah(output, first, second); + break; + default: + LOG(FATAL) << "Unexpected operation kind: " << op_kind; + UNREACHABLE(); + } + } else { + GenerateDataProcInstruction(kind, + output, + first, + Operand(second, + ShiftFromOpKind(op_kind), + instruction->GetShiftAmount()), + codegen_); + } } else { DCHECK_EQ(instruction->GetType(), Primitive::kPrimLong); diff --git a/compiler/optimizing/common_arm.h b/compiler/optimizing/common_arm.h index 01304ac35b..8fcceedcf6 100644 --- a/compiler/optimizing/common_arm.h +++ b/compiler/optimizing/common_arm.h @@ -227,14 +227,6 @@ inline Location LocationFrom(const vixl::aarch32::SRegister& low, return Location::FpuRegisterPairLocation(low.GetCode(), high.GetCode()); } -inline bool ShifterOperandSupportsExtension(HInstruction* instruction) { - DCHECK(HasShifterOperand(instruction, kArm)); - // TODO: HAdd applied to the other integral types could make use of - // the SXTAB, SXTAH, UXTAB and UXTAH instructions. - return instruction->GetType() == Primitive::kPrimLong && - (instruction->IsAdd() || instruction->IsSub()); -} - } // namespace helpers } // namespace arm } // namespace art diff --git a/compiler/optimizing/instruction_simplifier_arm.cc b/compiler/optimizing/instruction_simplifier_arm.cc index fe22595258..a025fb10ce 100644 --- a/compiler/optimizing/instruction_simplifier_arm.cc +++ b/compiler/optimizing/instruction_simplifier_arm.cc @@ -29,8 +29,6 @@ using helpers::HasShifterOperand; namespace arm { -using helpers::ShifterOperandSupportsExtension; - bool InstructionSimplifierArmVisitor::TryMergeIntoShifterOperand(HInstruction* use, HInstruction* bitfield_op, bool do_merge) { @@ -76,7 +74,7 @@ bool InstructionSimplifierArmVisitor::TryMergeIntoShifterOperand(HInstruction* u : kMaxLongShiftDistance; if (HDataProcWithShifterOp::IsExtensionOp(op_kind)) { - if (!ShifterOperandSupportsExtension(use)) { + if (!use->IsAdd() && (!use->IsSub() || use->GetType() != Primitive::kPrimLong)) { return false; } // Shift by 1 is a special case that results in the same number and type of instructions diff --git a/compiler/optimizing/scheduler_arm.cc b/compiler/optimizing/scheduler_arm.cc index e78cd78aa2..627ab4e2da 100644 --- a/compiler/optimizing/scheduler_arm.cc +++ b/compiler/optimizing/scheduler_arm.cc @@ -269,7 +269,6 @@ void SchedulingLatencyVisitorARM::VisitDataProcWithShifterOp(HDataProcWithShifte const HDataProcWithShifterOp::OpKind op_kind = instruction->GetOpKind(); if (instruction->GetType() == Primitive::kPrimInt) { - DCHECK(!HDataProcWithShifterOp::IsExtensionOp(op_kind)); HandleGenerateDataProcInstruction(); } else { DCHECK_EQ(instruction->GetType(), Primitive::kPrimLong); |