From 2961b849b46d84d06284d88f80b5950a1a4860d5 Mon Sep 17 00:00:00 2001 From: Lifang Xia Date: Tue, 20 Jun 2023 15:11:43 +0800 Subject: RISCV: [Codegen] Add VisitCompare Test: m test-art-host-gtest Bug: 283082089 Signed-off-by: Lifang Xia Signed-off-by: Wendong Wang Change-Id: I5fdaf57baddb8a8b1fa5128cd4bd98fd73bcb65d --- compiler/optimizing/code_generator_riscv64.cc | 113 +++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 4 deletions(-) (limited to 'compiler/optimizing') diff --git a/compiler/optimizing/code_generator_riscv64.cc b/compiler/optimizing/code_generator_riscv64.cc index 6266461afe..7a99adcd21 100644 --- a/compiler/optimizing/code_generator_riscv64.cc +++ b/compiler/optimizing/code_generator_riscv64.cc @@ -43,6 +43,21 @@ static constexpr FRegister kFpuCalleeSaves[] = { #define QUICK_ENTRY_POINT(x) QUICK_ENTRYPOINT_OFFSET(kRiscv64PointerSize, x).Int32Value() +Location RegisterOrZeroBitPatternLocation(HInstruction* instruction) { + return IsZeroBitPattern(instruction) + ? Location::ConstantLocation(instruction->AsConstant()) + : Location::RequiresRegister(); +} + +XRegister InputXRegisterOrZero(Location location) { + if (location.IsConstant()) { + DCHECK(location.GetConstant()->IsZeroBitPattern()); + return Zero; + } else { + return location.AsRegister(); + } +} + Location Riscv64ReturnLocation(DataType::Type return_type) { switch (return_type) { case DataType::Type::kBool: @@ -1188,13 +1203,103 @@ void InstructionCodeGeneratorRISCV64::VisitClinitCheck(HClinitCheck* instruction } void LocationsBuilderRISCV64::VisitCompare(HCompare* instruction) { - UNUSED(instruction); - LOG(FATAL) << "Unimplemented"; + DataType::Type in_type = instruction->InputAt(0)->GetType(); + + LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(instruction); + + switch (in_type) { + case DataType::Type::kBool: + case DataType::Type::kUint8: + case DataType::Type::kInt8: + case DataType::Type::kUint16: + case DataType::Type::kInt16: + case DataType::Type::kInt32: + case DataType::Type::kInt64: + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, RegisterOrZeroBitPatternLocation(instruction->InputAt(1))); + locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); + break; + + case DataType::Type::kFloat32: + case DataType::Type::kFloat64: + locations->SetInAt(0, Location::RequiresFpuRegister()); + locations->SetInAt(1, Location::RequiresFpuRegister()); + locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); + break; + + default: + LOG(FATAL) << "Unexpected type for compare operation " << in_type; + UNREACHABLE(); + } } void InstructionCodeGeneratorRISCV64::VisitCompare(HCompare* instruction) { - UNUSED(instruction); - LOG(FATAL) << "Unimplemented"; + LocationSummary* locations = instruction->GetLocations(); + XRegister result = locations->Out().AsRegister(); + DataType::Type in_type = instruction->InputAt(0)->GetType(); + + // 0 if: left == right + // 1 if: left > right + // -1 if: left < right + switch (in_type) { + case DataType::Type::kBool: + case DataType::Type::kUint8: + case DataType::Type::kInt8: + case DataType::Type::kUint16: + case DataType::Type::kInt16: + case DataType::Type::kInt32: + case DataType::Type::kInt64: { + XRegister left = locations->InAt(0).AsRegister(); + XRegister right = InputXRegisterOrZero(locations->InAt(1)); + ScratchRegisterScope srs(GetAssembler()); + XRegister tmp = srs.AllocateXRegister(); + __ Slt(tmp, left, right); + __ Slt(result, right, left); + __ Sub(result, result, tmp); + break; + } + + case DataType::Type::kFloat32: { + FRegister left = locations->InAt(0).AsFpuRegister(); + FRegister right = locations->InAt(1).AsFpuRegister(); + ScratchRegisterScope srs(GetAssembler()); + XRegister tmp = srs.AllocateXRegister(); + if (instruction->IsGtBias()) { + __ FLeS(tmp, left, right); + __ FLtS(result, left, right); + __ Xori(tmp, tmp, 1); + __ Sub(result, tmp, result); + } else { + __ FLeS(tmp, right, left); + __ FLtS(result, right, left); + __ Addi(tmp, tmp, -1); + __ Add(result, result, tmp); + } + break; + } + + case DataType::Type::kFloat64: { + FRegister left = locations->InAt(0).AsFpuRegister(); + FRegister right = locations->InAt(1).AsFpuRegister(); + ScratchRegisterScope srs(GetAssembler()); + XRegister tmp = srs.AllocateXRegister(); + if (instruction->IsGtBias()) { + __ FLeD(tmp, left, right); + __ FLtD(result, left, right); + __ Xori(tmp, tmp, 1); + __ Sub(result, tmp, result); + } else { + __ FLeD(tmp, right, left); + __ FLtD(result, right, left); + __ Addi(tmp, tmp, -1); + __ Add(result, result, tmp); + } + break; + } + + default: + LOG(FATAL) << "Unimplemented compare type " << in_type; + } } void LocationsBuilderRISCV64::VisitConstructorFence(HConstructorFence* instruction) { -- cgit v1.2.3-59-g8ed1b