summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator_arm.cc
diff options
context:
space:
mode:
authorDavid Brazdil <dbrazdil@google.com>2015-12-14 11:44:01 +0000
committerDavid Brazdil <dbrazdil@google.com>2016-01-28 15:50:27 +0000
commit74eb1b264691c4eb399d0858015a7fc13c476ac6 (patch)
tree0b6fc4f3003d50bf6c388601013cdfc606e53859 /compiler/optimizing/code_generator_arm.cc
parent75fd2a8ab9b4aff59308034da26eb4986d10fa9e (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.cc50
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 {