From 4375819125bce2132cde663ba5024e33d7bd2681 Mon Sep 17 00:00:00 2001 From: Tijana Jakovljevic Date: Fri, 30 Dec 2016 09:23:01 +0100 Subject: [PATCH] MIPS64: Implement branchless HCondition for floats Test: mma test-art-target-run-test64 in QEMU Change-Id: I595b5b7ddf9ebb19e872ed85f2e4098a835d9214 --- compiler/optimizing/code_generator_mips64.cc | 140 ++++++++++++++++++++++----- compiler/optimizing/code_generator_mips64.h | 4 + 2 files changed, 121 insertions(+), 23 deletions(-) diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index cdbc712f8..799360ebd 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -1929,9 +1929,6 @@ void InstructionCodeGeneratorMIPS64::HandleCondition(HCondition* instruction) { Primitive::Type type = instruction->InputAt(0)->GetType(); LocationSummary* locations = instruction->GetLocations(); - GpuRegister dst = locations->Out().AsRegister(); - Mips64Label true_label; - switch (type) { default: // Integer case. @@ -1940,29 +1937,11 @@ void InstructionCodeGeneratorMIPS64::HandleCondition(HCondition* instruction) { case Primitive::kPrimLong: GenerateIntLongCompare(instruction->GetCondition(), /* is64bit */ true, locations); return; - case Primitive::kPrimFloat: case Primitive::kPrimDouble: - // TODO: don't use branches. - GenerateFpCompareAndBranch(instruction->GetCondition(), - instruction->IsGtBias(), - type, - locations, - &true_label); - break; + GenerateFpCompare(instruction->GetCondition(), instruction->IsGtBias(), type, locations); + return; } - - // Convert the branches into the result. - Mips64Label done; - - // False case: result = 0. - __ LoadConst32(dst, 0); - __ Bc(&done); - - // True case: result = 1. - __ Bind(&true_label); - __ LoadConst32(dst, 1); - __ Bind(&done); } void InstructionCodeGeneratorMIPS64::DivRemOneOrMinusOne(HBinaryOperation* instruction) { @@ -2576,6 +2555,121 @@ void InstructionCodeGeneratorMIPS64::GenerateIntLongCompareAndBranch(IfCondition } } +void InstructionCodeGeneratorMIPS64::GenerateFpCompare(IfCondition cond, + bool gt_bias, + Primitive::Type type, + LocationSummary* locations) { + GpuRegister dst = locations->Out().AsRegister(); + FpuRegister lhs = locations->InAt(0).AsFpuRegister(); + FpuRegister rhs = locations->InAt(1).AsFpuRegister(); + if (type == Primitive::kPrimFloat) { + switch (cond) { + case kCondEQ: + __ CmpEqS(FTMP, lhs, rhs); + __ Mfc1(dst, FTMP); + __ Andi(dst, dst, 1); + break; + case kCondNE: + __ CmpEqS(FTMP, lhs, rhs); + __ Mfc1(dst, FTMP); + __ Addiu(dst, dst, 1); + break; + case kCondLT: + if (gt_bias) { + __ CmpLtS(FTMP, lhs, rhs); + } else { + __ CmpUltS(FTMP, lhs, rhs); + } + __ Mfc1(dst, FTMP); + __ Andi(dst, dst, 1); + break; + case kCondLE: + if (gt_bias) { + __ CmpLeS(FTMP, lhs, rhs); + } else { + __ CmpUleS(FTMP, lhs, rhs); + } + __ Mfc1(dst, FTMP); + __ Andi(dst, dst, 1); + break; + case kCondGT: + if (gt_bias) { + __ CmpUltS(FTMP, rhs, lhs); + } else { + __ CmpLtS(FTMP, rhs, lhs); + } + __ Mfc1(dst, FTMP); + __ Andi(dst, dst, 1); + break; + case kCondGE: + if (gt_bias) { + __ CmpUleS(FTMP, rhs, lhs); + } else { + __ CmpLeS(FTMP, rhs, lhs); + } + __ Mfc1(dst, FTMP); + __ Andi(dst, dst, 1); + break; + default: + LOG(FATAL) << "Unexpected non-floating-point condition " << cond; + UNREACHABLE(); + } + } else { + DCHECK_EQ(type, Primitive::kPrimDouble); + switch (cond) { + case kCondEQ: + __ CmpEqD(FTMP, lhs, rhs); + __ Mfc1(dst, FTMP); + __ Andi(dst, dst, 1); + break; + case kCondNE: + __ CmpEqD(FTMP, lhs, rhs); + __ Mfc1(dst, FTMP); + __ Addiu(dst, dst, 1); + break; + case kCondLT: + if (gt_bias) { + __ CmpLtD(FTMP, lhs, rhs); + } else { + __ CmpUltD(FTMP, lhs, rhs); + } + __ Mfc1(dst, FTMP); + __ Andi(dst, dst, 1); + break; + case kCondLE: + if (gt_bias) { + __ CmpLeD(FTMP, lhs, rhs); + } else { + __ CmpUleD(FTMP, lhs, rhs); + } + __ Mfc1(dst, FTMP); + __ Andi(dst, dst, 1); + break; + case kCondGT: + if (gt_bias) { + __ CmpUltD(FTMP, rhs, lhs); + } else { + __ CmpLtD(FTMP, rhs, lhs); + } + __ Mfc1(dst, FTMP); + __ Andi(dst, dst, 1); + break; + case kCondGE: + if (gt_bias) { + __ CmpUleD(FTMP, rhs, lhs); + } else { + __ CmpLeD(FTMP, rhs, lhs); + } + __ Mfc1(dst, FTMP); + __ Andi(dst, dst, 1); + break; + default: + LOG(FATAL) << "Unexpected non-floating-point condition " << cond; + UNREACHABLE(); + } + } +} + void InstructionCodeGeneratorMIPS64::GenerateFpCompareAndBranch(IfCondition cond, bool gt_bias, Primitive::Type type, diff --git a/compiler/optimizing/code_generator_mips64.h b/compiler/optimizing/code_generator_mips64.h index 5e049aedc..027121986 100644 --- a/compiler/optimizing/code_generator_mips64.h +++ b/compiler/optimizing/code_generator_mips64.h @@ -250,6 +250,10 @@ class InstructionCodeGeneratorMIPS64 : public InstructionCodeGenerator { bool is64bit, LocationSummary* locations, Mips64Label* label); + void GenerateFpCompare(IfCondition cond, + bool gt_bias, + Primitive::Type type, + LocationSummary* locations); void GenerateFpCompareAndBranch(IfCondition cond, bool gt_bias, Primitive::Type type, -- 2.11.0