Skip to content

Commit

Permalink
8318723: RISC-V: C2 UDivL
Browse files Browse the repository at this point in the history
8318224: RISC-V: C2 UDivI

Reviewed-by: fyang, luhenry, aph
  • Loading branch information
Hamlin Li committed Oct 26, 2023
1 parent 3885dc5 commit 40a3c35
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 23 deletions.
10 changes: 7 additions & 3 deletions src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right,
}
} else {
Register rreg = right->as_register();
__ corrected_idivl(dreg, lreg, rreg, is_irem);
__ corrected_idivl(dreg, lreg, rreg, is_irem, /* is_signed */ true);
}
}

Expand Down Expand Up @@ -172,8 +172,12 @@ void LIR_Assembler::arith_op_double_cpu(LIR_Code code, LIR_Opr left, LIR_Opr rig
case lir_add: __ add(dest->as_register_lo(), lreg_lo, rreg_lo); break;
case lir_sub: __ sub(dest->as_register_lo(), lreg_lo, rreg_lo); break;
case lir_mul: __ mul(dest->as_register_lo(), lreg_lo, rreg_lo); break;
case lir_div: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo, false); break;
case lir_rem: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo, true); break;
case lir_div: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo,
/* want_remainder */ false, /* is_signed */ true);
break;
case lir_rem: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo,
/* want_remainder */ true, /* is_signed */ true);
break;
default:
ShouldNotReachHere();
}
Expand Down
16 changes: 12 additions & 4 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2386,7 +2386,7 @@ void MacroAssembler::store_heap_oop_null(Address dst) {
}

int MacroAssembler::corrected_idivl(Register result, Register rs1, Register rs2,
bool want_remainder)
bool want_remainder, bool is_signed)
{
// Full implementation of Java idiv and irem. The function
// returns the (pc) offset of the div instruction - may be needed
Expand All @@ -2402,15 +2402,19 @@ int MacroAssembler::corrected_idivl(Register result, Register rs1, Register rs2,

int idivl_offset = offset();
if (!want_remainder) {
divw(result, rs1, rs2);
if (is_signed) {
divw(result, rs1, rs2);
} else {
divuw(result, rs1, rs2);
}
} else {
remw(result, rs1, rs2); // result = rs1 % rs2;
}
return idivl_offset;
}

int MacroAssembler::corrected_idivq(Register result, Register rs1, Register rs2,
bool want_remainder)
bool want_remainder, bool is_signed)
{
// Full implementation of Java ldiv and lrem. The function
// returns the (pc) offset of the div instruction - may be needed
Expand All @@ -2425,7 +2429,11 @@ int MacroAssembler::corrected_idivq(Register result, Register rs1, Register rs2,

int idivq_offset = offset();
if (!want_remainder) {
div(result, rs1, rs2);
if (is_signed) {
div(result, rs1, rs2);
} else {
divu(result, rs1, rs2);
}
} else {
rem(result, rs1, rs2); // result = rs1 % rs2;
}
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ class MacroAssembler: public Assembler {

// idiv variant which deals with MINLONG as dividend and -1 as divisor
int corrected_idivl(Register result, Register rs1, Register rs2,
bool want_remainder);
bool want_remainder, bool is_signed);
int corrected_idivq(Register result, Register rs1, Register rs2,
bool want_remainder);
bool want_remainder, bool is_signed);

// interface method calling
void lookup_interface_method(Register recv_klass,
Expand Down
43 changes: 39 additions & 4 deletions src/hotspot/cpu/riscv/riscv.ad
Original file line number Diff line number Diff line change
Expand Up @@ -2443,31 +2443,47 @@ encode %{
Register dst_reg = as_Register($dst$$reg);
Register src1_reg = as_Register($src1$$reg);
Register src2_reg = as_Register($src2$$reg);
__ corrected_idivl(dst_reg, src1_reg, src2_reg, false);
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ true);
%}

enc_class riscv_enc_divuw(iRegI dst, iRegI src1, iRegI src2) %{
C2_MacroAssembler _masm(&cbuf);
Register dst_reg = as_Register($dst$$reg);
Register src1_reg = as_Register($src1$$reg);
Register src2_reg = as_Register($src2$$reg);
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ false);
%}

enc_class riscv_enc_div(iRegI dst, iRegI src1, iRegI src2) %{
C2_MacroAssembler _masm(&cbuf);
Register dst_reg = as_Register($dst$$reg);
Register src1_reg = as_Register($src1$$reg);
Register src2_reg = as_Register($src2$$reg);
__ corrected_idivq(dst_reg, src1_reg, src2_reg, false);
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ true);
%}

enc_class riscv_enc_divu(iRegI dst, iRegI src1, iRegI src2) %{
C2_MacroAssembler _masm(&cbuf);
Register dst_reg = as_Register($dst$$reg);
Register src1_reg = as_Register($src1$$reg);
Register src2_reg = as_Register($src2$$reg);
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ false);
%}

enc_class riscv_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{
C2_MacroAssembler _masm(&cbuf);
Register dst_reg = as_Register($dst$$reg);
Register src1_reg = as_Register($src1$$reg);
Register src2_reg = as_Register($src2$$reg);
__ corrected_idivl(dst_reg, src1_reg, src2_reg, true);
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ true);
%}

enc_class riscv_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{
C2_MacroAssembler _masm(&cbuf);
Register dst_reg = as_Register($dst$$reg);
Register src1_reg = as_Register($src1$$reg);
Register src2_reg = as_Register($src2$$reg);
__ corrected_idivq(dst_reg, src1_reg, src2_reg, true);
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ true);
%}

enc_class riscv_enc_tail_call(iRegP jump_target) %{
Expand Down Expand Up @@ -6673,6 +6689,15 @@ instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
ins_pipe(idiv_reg_reg);
%}

instruct UdivI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
match(Set dst (UDivI src1 src2));
ins_cost(IDIVSI_COST);
format %{ "divuw $dst, $src1, $src2\t#@UdivI"%}

ins_encode(riscv_enc_divuw(dst, src1, src2));
ins_pipe(idiv_reg_reg);
%}

instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{
match(Set dst (URShiftI (RShiftI src1 div1) div2));
ins_cost(ALU_COST);
Expand All @@ -6695,6 +6720,16 @@ instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
ins_pipe(ldiv_reg_reg);
%}

instruct UdivL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
match(Set dst (UDivL src1 src2));
ins_cost(IDIVDI_COST);

format %{ "divu $dst, $src1, $src2\t#@UdivL" %}

ins_encode(riscv_enc_divu(dst, src1, src2));
ins_pipe(ldiv_reg_reg);
%}

instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{
match(Set dst (URShiftL (RShiftL src1 div1) div2));
ins_cost(ALU_COST);
Expand Down
8 changes: 4 additions & 4 deletions src/hotspot/cpu/riscv/templateTable_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1318,7 +1318,7 @@ void TemplateTable::idiv() {
__ bind(no_div0);
__ pop_i(x11);
// x10 <== x11 idiv x10
__ corrected_idivl(x10, x11, x10, /* want_remainder */ false);
__ corrected_idivl(x10, x11, x10, /* want_remainder */ false, /* is_signed */ true);
}

void TemplateTable::irem() {
Expand All @@ -1331,7 +1331,7 @@ void TemplateTable::irem() {
__ bind(no_div0);
__ pop_i(x11);
// x10 <== x11 irem x10
__ corrected_idivl(x10, x11, x10, /* want_remainder */ true);
__ corrected_idivl(x10, x11, x10, /* want_remainder */ true, /* is_signed */ true);
}

void TemplateTable::lmul() {
Expand All @@ -1350,7 +1350,7 @@ void TemplateTable::ldiv() {
__ bind(no_div0);
__ pop_l(x11);
// x10 <== x11 ldiv x10
__ corrected_idivq(x10, x11, x10, /* want_remainder */ false);
__ corrected_idivq(x10, x11, x10, /* want_remainder */ false, /* is_signed */ true);
}

void TemplateTable::lrem() {
Expand All @@ -1363,7 +1363,7 @@ void TemplateTable::lrem() {
__ bind(no_div0);
__ pop_l(x11);
// x10 <== x11 lrem x10
__ corrected_idivq(x10, x11, x10, /* want_remainder */ true);
__ corrected_idivq(x10, x11, x10, /* want_remainder */ true, /* is_signed */ true);
}

void TemplateTable::lshl() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -23,8 +23,8 @@

/**
* @test
* @summary Test x86_64 intrinsic for divideUnsigned() and remainderUnsigned() methods for Integer
* @requires os.arch=="amd64" | os.arch=="x86_64"
* @summary Test intrinsic for divideUnsigned() and remainderUnsigned() methods for Integer
* @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="riscv64"
* @library /test/lib /
* @run driver compiler.intrinsics.TestIntegerUnsignedDivMod
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -23,8 +23,8 @@

/**
* @test
* @summary Test x86_64 intrinsic for divideUnsigned() and remainderUnsigned() methods for Long
* @requires os.arch=="amd64" | os.arch=="x86_64"
* @summary Test intrinsic for divideUnsigned() and remainderUnsigned() methods for Long
* @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="riscv64"
* @library /test/lib /
* @run driver compiler.intrinsics.TestLongUnsignedDivMod
*/
Expand Down

1 comment on commit 40a3c35

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.