diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/optimizing/code_generator_riscv64.h | 13 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_riscv64.cc | 144 |
2 files changed, 144 insertions, 13 deletions
diff --git a/compiler/optimizing/code_generator_riscv64.h b/compiler/optimizing/code_generator_riscv64.h index 6a10b3a4c3..85a210c968 100644 --- a/compiler/optimizing/code_generator_riscv64.h +++ b/compiler/optimizing/code_generator_riscv64.h @@ -50,22 +50,9 @@ static constexpr size_t kRuntimeParameterFpuRegistersLength = #define UNIMPLEMENTED_INTRINSIC_LIST_RISCV64(V) \ V(IntegerReverse) \ - V(IntegerReverseBytes) \ - V(IntegerBitCount) \ V(IntegerDivideUnsigned) \ - V(IntegerHighestOneBit) \ - V(IntegerLowestOneBit) \ - V(IntegerNumberOfLeadingZeros) \ - V(IntegerNumberOfTrailingZeros) \ V(LongReverse) \ - V(LongReverseBytes) \ - V(LongBitCount) \ V(LongDivideUnsigned) \ - V(LongHighestOneBit) \ - V(LongLowestOneBit) \ - V(LongNumberOfLeadingZeros) \ - V(LongNumberOfTrailingZeros) \ - V(ShortReverseBytes) \ V(MathFmaDouble) \ V(MathFmaFloat) \ V(MathCos) \ diff --git a/compiler/optimizing/intrinsics_riscv64.cc b/compiler/optimizing/intrinsics_riscv64.cc index f1d4b44c10..668b3862ad 100644 --- a/compiler/optimizing/intrinsics_riscv64.cc +++ b/compiler/optimizing/intrinsics_riscv64.cc @@ -200,6 +200,150 @@ void IntrinsicCodeGeneratorRISCV64::VisitMemoryPokeShortNative(HInvoke* invoke) EmitMemoryPoke(invoke, [&](XRegister rs2, XRegister rs1) { __ Sh(rs2, rs1, 0); }); } +template <typename EmitOp> +void EmitIntegralUnOp(HInvoke* invoke, EmitOp&& emit_op) { + LocationSummary* locations = invoke->GetLocations(); + emit_op(locations->Out().AsRegister<XRegister>(), locations->InAt(0).AsRegister<XRegister>()); +} + +void IntrinsicLocationsBuilderRISCV64::VisitIntegerReverseBytes(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitIntegerReverseBytes(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { + // There is no 32-bit reverse bytes instruction. + __ Rev8(rd, rs1); + __ Srai(rd, rd, 32); + }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitLongReverseBytes(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitLongReverseBytes(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { __ Rev8(rd, rs1); }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitShortReverseBytes(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitShortReverseBytes(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { + // There is no 16-bit reverse bytes instruction. + __ Rev8(rd, rs1); + __ Srai(rd, rd, 48); + }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitIntegerBitCount(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitIntegerBitCount(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { __ Cpopw(rd, rs1); }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitLongBitCount(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitLongBitCount(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { __ Cpop(rd, rs1); }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitIntegerHighestOneBit(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitIntegerHighestOneBit(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { + ScratchRegisterScope srs(GetAssembler()); + XRegister tmp = srs.AllocateXRegister(); + XRegister tmp2 = srs.AllocateXRegister(); + __ Clzw(tmp, rs1); + __ Li(tmp2, INT64_C(-0x80000000)); + __ Srlw(tmp2, tmp2, tmp); + __ And(rd, rs1, tmp2); // Make sure the result is zero if the input is zero. + }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitLongHighestOneBit(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitLongHighestOneBit(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { + ScratchRegisterScope srs(GetAssembler()); + XRegister tmp = srs.AllocateXRegister(); + XRegister tmp2 = srs.AllocateXRegister(); + __ Clz(tmp, rs1); + __ Li(tmp2, INT64_C(-0x8000000000000000)); + __ Srl(tmp2, tmp2, tmp); + __ And(rd, rs1, tmp2); // Make sure the result is zero if the input is zero. + }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitIntegerLowestOneBit(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitIntegerLowestOneBit(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { + ScratchRegisterScope srs(GetAssembler()); + XRegister tmp = srs.AllocateXRegister(); + __ NegW(tmp, rs1); + __ And(rd, rs1, tmp); + }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitLongLowestOneBit(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitLongLowestOneBit(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { + ScratchRegisterScope srs(GetAssembler()); + XRegister tmp = srs.AllocateXRegister(); + __ Neg(tmp, rs1); + __ And(rd, rs1, tmp); + }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitIntegerNumberOfLeadingZeros(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitIntegerNumberOfLeadingZeros(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { __ Clzw(rd, rs1); }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitLongNumberOfLeadingZeros(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitLongNumberOfLeadingZeros(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { __ Clz(rd, rs1); }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitIntegerNumberOfTrailingZeros(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitIntegerNumberOfTrailingZeros(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { __ Ctzw(rd, rs1); }); +} + +void IntrinsicLocationsBuilderRISCV64::VisitLongNumberOfTrailingZeros(HInvoke* invoke) { + CreateIntToIntLocations(allocator_, invoke); +} + +void IntrinsicCodeGeneratorRISCV64::VisitLongNumberOfTrailingZeros(HInvoke* invoke) { + EmitIntegralUnOp(invoke, [&](XRegister rd, XRegister rs1) { __ Ctz(rd, rs1); }); +} + #define MARK_UNIMPLEMENTED(Name) UNIMPLEMENTED_INTRINSIC(RISCV64, Name) UNIMPLEMENTED_INTRINSIC_LIST_RISCV64(MARK_UNIMPLEMENTED); #undef MARK_UNIMPLEMENTED |