diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-11-12 13:19:37 +0000 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-11-12 13:55:36 +0000 |
commit | 9574c4b5f5ef039d694ac12c97e25ca02eca83c0 (patch) | |
tree | 2ad3cb7ffaf3579b9ca2a7bb0d7d7e99b3c758b6 /compiler/optimizing/code_generator_arm.cc | |
parent | 59321e0e10ea09694efecf6154704e2743b9bffd (diff) | |
download | art-9574c4b5f5ef039d694ac12c97e25ca02eca83c0.tar.gz art-9574c4b5f5ef039d694ac12c97e25ca02eca83c0.tar.bz2 art-9574c4b5f5ef039d694ac12c97e25ca02eca83c0.zip |
Implement and/or/xor in optimizing.
Change-Id: I7cf6da1fd334a7177a5580931b8f174dd40b7cec
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index c2e9a2e5da..56546c2901 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -2809,5 +2809,78 @@ void InstructionCodeGeneratorARM::VisitMonitorOperation(HMonitorOperation* instr instruction->GetDexPc()); } +void LocationsBuilderARM::VisitAnd(HAnd* instruction) { HandleBitwiseOperation(instruction); } +void LocationsBuilderARM::VisitOr(HOr* instruction) { HandleBitwiseOperation(instruction); } +void LocationsBuilderARM::VisitXor(HXor* instruction) { HandleBitwiseOperation(instruction); } + +void LocationsBuilderARM::HandleBitwiseOperation(HBinaryOperation* instruction) { + LocationSummary* locations = + new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); + DCHECK(instruction->GetResultType() == Primitive::kPrimInt + || instruction->GetResultType() == Primitive::kPrimLong); + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, Location::RequiresRegister()); + bool output_overlaps = (instruction->GetResultType() == Primitive::kPrimLong); + locations->SetOut(Location::RequiresRegister(), output_overlaps); +} + +void InstructionCodeGeneratorARM::VisitAnd(HAnd* instruction) { + HandleBitwiseOperation(instruction); +} + +void InstructionCodeGeneratorARM::VisitOr(HOr* instruction) { + HandleBitwiseOperation(instruction); +} + +void InstructionCodeGeneratorARM::VisitXor(HXor* instruction) { + HandleBitwiseOperation(instruction); +} + +void InstructionCodeGeneratorARM::HandleBitwiseOperation(HBinaryOperation* instruction) { + LocationSummary* locations = instruction->GetLocations(); + + if (instruction->GetResultType() == Primitive::kPrimInt) { + Register first = locations->InAt(0).As<Register>(); + Register second = locations->InAt(1).As<Register>(); + Register out = locations->Out().As<Register>(); + if (instruction->IsAnd()) { + __ and_(out, first, ShifterOperand(second)); + } else if (instruction->IsOr()) { + __ orr(out, first, ShifterOperand(second)); + } else { + DCHECK(instruction->IsXor()); + __ eor(out, first, ShifterOperand(second)); + } + } else { + DCHECK_EQ(instruction->GetResultType(), Primitive::kPrimLong); + Location first = locations->InAt(0); + Location second = locations->InAt(1); + Location out = locations->Out(); + if (instruction->IsAnd()) { + __ and_(out.AsRegisterPairLow<Register>(), + first.AsRegisterPairLow<Register>(), + ShifterOperand(second.AsRegisterPairLow<Register>())); + __ and_(out.AsRegisterPairHigh<Register>(), + first.AsRegisterPairHigh<Register>(), + ShifterOperand(second.AsRegisterPairHigh<Register>())); + } else if (instruction->IsOr()) { + __ orr(out.AsRegisterPairLow<Register>(), + first.AsRegisterPairLow<Register>(), + ShifterOperand(second.AsRegisterPairLow<Register>())); + __ orr(out.AsRegisterPairHigh<Register>(), + first.AsRegisterPairHigh<Register>(), + ShifterOperand(second.AsRegisterPairHigh<Register>())); + } else { + DCHECK(instruction->IsXor()); + __ eor(out.AsRegisterPairLow<Register>(), + first.AsRegisterPairLow<Register>(), + ShifterOperand(second.AsRegisterPairLow<Register>())); + __ eor(out.AsRegisterPairHigh<Register>(), + first.AsRegisterPairHigh<Register>(), + ShifterOperand(second.AsRegisterPairHigh<Register>())); + } + } +} + } // namespace arm } // namespace art |