diff options
author | David Brazdil <dbrazdil@google.com> | 2015-12-14 11:44:01 +0000 |
---|---|---|
committer | David Brazdil <dbrazdil@google.com> | 2016-01-28 15:50:27 +0000 |
commit | 74eb1b264691c4eb399d0858015a7fc13c476ac6 (patch) | |
tree | 0b6fc4f3003d50bf6c388601013cdfc606e53859 /compiler/optimizing/code_generator_arm.cc | |
parent | 75fd2a8ab9b4aff59308034da26eb4986d10fa9e (diff) |
ART: Implement HSelect
This patch adds a new HIR instruction to Optimizing. HSelect returns
one of two inputs based on the outcome of a condition.
This is only initial implementation which:
- defines the new instruction,
- repurposes BooleanSimplifier to emit it,
- extends InstructionSimplifier to statically resolve it,
- updates existing code and tests accordingly.
Code generators currently emit fallback if/then/else code and will be
updated in follow-up CLs to use platform-specific conditional moves
when possible.
Change-Id: Ib61b17146487ebe6b55350c2b589f0b971dcaaee
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 2b81dba0f9..894ee07222 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -1285,11 +1285,9 @@ void CodeGeneratorARM::MoveConstant(Location location, int32_t value) { } void CodeGeneratorARM::MoveLocation(Location dst, Location src, Primitive::Type dst_type) { - if (Primitive::Is64BitType(dst_type)) { - Move64(dst, src); - } else { - Move32(dst, src); - } + HParallelMove move(GetGraph()->GetArena()); + move.AddMove(src, dst, dst_type, nullptr); + GetMoveResolver()->EmitNativeCode(&move); } void CodeGeneratorARM::AddLocationAsTemp(Location location, LocationSummary* locations) { @@ -1612,6 +1610,32 @@ void InstructionCodeGeneratorARM::VisitDeoptimize(HDeoptimize* deoptimize) { /* false_target */ nullptr); } +void LocationsBuilderARM::VisitSelect(HSelect* select) { + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(select); + if (Primitive::IsFloatingPointType(select->GetType())) { + locations->SetInAt(0, Location::RequiresFpuRegister()); + locations->SetInAt(1, Location::RequiresFpuRegister()); + } else { + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, Location::RequiresRegister()); + } + if (IsBooleanValueOrMaterializedCondition(select->GetCondition())) { + locations->SetInAt(2, Location::RequiresRegister()); + } + locations->SetOut(Location::SameAsFirstInput()); +} + +void InstructionCodeGeneratorARM::VisitSelect(HSelect* select) { + LocationSummary* locations = select->GetLocations(); + Label false_target; + GenerateTestAndBranch(select, + /* condition_input_index */ 2, + /* true_target */ nullptr, + &false_target); + codegen_->MoveLocation(locations->Out(), locations->InAt(1), select->GetType()); + __ Bind(&false_target); +} + void LocationsBuilderARM::VisitNativeDebugInfo(HNativeDebugInfo* info) { new (GetGraph()->GetArena()) LocationSummary(info); } @@ -4973,6 +4997,8 @@ void ParallelMoveResolverARM::EmitMove(size_t index) { if (source.IsRegister()) { if (destination.IsRegister()) { __ Mov(destination.AsRegister<Register>(), source.AsRegister<Register>()); + } else if (destination.IsFpuRegister()) { + __ vmovsr(destination.AsFpuRegister<SRegister>(), source.AsRegister<Register>()); } else { DCHECK(destination.IsStackSlot()); __ StoreToOffset(kStoreWord, source.AsRegister<Register>(), @@ -4990,7 +5016,9 @@ void ParallelMoveResolverARM::EmitMove(size_t index) { __ StoreToOffset(kStoreWord, IP, SP, destination.GetStackIndex()); } } else if (source.IsFpuRegister()) { - if (destination.IsFpuRegister()) { + if (destination.IsRegister()) { + __ vmovrs(destination.AsRegister<Register>(), source.AsFpuRegister<SRegister>()); + } else if (destination.IsFpuRegister()) { __ vmovs(destination.AsFpuRegister<SRegister>(), source.AsFpuRegister<SRegister>()); } else { DCHECK(destination.IsStackSlot()); @@ -5014,6 +5042,10 @@ void ParallelMoveResolverARM::EmitMove(size_t index) { if (destination.IsRegisterPair()) { __ Mov(destination.AsRegisterPairLow<Register>(), source.AsRegisterPairLow<Register>()); __ Mov(destination.AsRegisterPairHigh<Register>(), source.AsRegisterPairHigh<Register>()); + } else if (destination.IsFpuRegisterPair()) { + __ vmovdrr(FromLowSToD(destination.AsFpuRegisterPairLow<SRegister>()), + source.AsRegisterPairLow<Register>(), + source.AsRegisterPairHigh<Register>()); } else { DCHECK(destination.IsDoubleStackSlot()) << destination; DCHECK(ExpectedPairLayout(source)); @@ -5021,7 +5053,11 @@ void ParallelMoveResolverARM::EmitMove(size_t index) { kStoreWordPair, source.AsRegisterPairLow<Register>(), SP, destination.GetStackIndex()); } } else if (source.IsFpuRegisterPair()) { - if (destination.IsFpuRegisterPair()) { + if (destination.IsRegisterPair()) { + __ vmovrrd(destination.AsRegisterPairLow<Register>(), + destination.AsRegisterPairHigh<Register>(), + FromLowSToD(source.AsFpuRegisterPairLow<SRegister>())); + } else if (destination.IsFpuRegisterPair()) { __ vmovd(FromLowSToD(destination.AsFpuRegisterPairLow<SRegister>()), FromLowSToD(source.AsFpuRegisterPairLow<SRegister>())); } else { |