Skip to content

Commit 8264605

Browse files
Hamlin Lipull[bot]
authored andcommitted
8318723: RISC-V: C2 UDivL
8318224: RISC-V: C2 UDivI Reviewed-by: fyang, luhenry, aph
1 parent d99813e commit 8264605

File tree

7 files changed

+70
-23
lines changed

7 files changed

+70
-23
lines changed

src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right,
8686
}
8787
} else {
8888
Register rreg = right->as_register();
89-
__ corrected_idivl(dreg, lreg, rreg, is_irem);
89+
__ corrected_idivl(dreg, lreg, rreg, is_irem, /* is_signed */ true);
9090
}
9191
}
9292

@@ -172,8 +172,12 @@ void LIR_Assembler::arith_op_double_cpu(LIR_Code code, LIR_Opr left, LIR_Opr rig
172172
case lir_add: __ add(dest->as_register_lo(), lreg_lo, rreg_lo); break;
173173
case lir_sub: __ sub(dest->as_register_lo(), lreg_lo, rreg_lo); break;
174174
case lir_mul: __ mul(dest->as_register_lo(), lreg_lo, rreg_lo); break;
175-
case lir_div: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo, false); break;
176-
case lir_rem: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo, true); break;
175+
case lir_div: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo,
176+
/* want_remainder */ false, /* is_signed */ true);
177+
break;
178+
case lir_rem: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo,
179+
/* want_remainder */ true, /* is_signed */ true);
180+
break;
177181
default:
178182
ShouldNotReachHere();
179183
}

src/hotspot/cpu/riscv/macroAssembler_riscv.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2386,7 +2386,7 @@ void MacroAssembler::store_heap_oop_null(Address dst) {
23862386
}
23872387

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

24032403
int idivl_offset = offset();
24042404
if (!want_remainder) {
2405-
divw(result, rs1, rs2);
2405+
if (is_signed) {
2406+
divw(result, rs1, rs2);
2407+
} else {
2408+
divuw(result, rs1, rs2);
2409+
}
24062410
} else {
24072411
remw(result, rs1, rs2); // result = rs1 % rs2;
24082412
}
24092413
return idivl_offset;
24102414
}
24112415

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

24262430
int idivq_offset = offset();
24272431
if (!want_remainder) {
2428-
div(result, rs1, rs2);
2432+
if (is_signed) {
2433+
div(result, rs1, rs2);
2434+
} else {
2435+
divu(result, rs1, rs2);
2436+
}
24292437
} else {
24302438
rem(result, rs1, rs2); // result = rs1 % rs2;
24312439
}

src/hotspot/cpu/riscv/macroAssembler_riscv.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,9 @@ class MacroAssembler: public Assembler {
241241

242242
// idiv variant which deals with MINLONG as dividend and -1 as divisor
243243
int corrected_idivl(Register result, Register rs1, Register rs2,
244-
bool want_remainder);
244+
bool want_remainder, bool is_signed);
245245
int corrected_idivq(Register result, Register rs1, Register rs2,
246-
bool want_remainder);
246+
bool want_remainder, bool is_signed);
247247

248248
// interface method calling
249249
void lookup_interface_method(Register recv_klass,

src/hotspot/cpu/riscv/riscv.ad

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2443,31 +2443,47 @@ encode %{
24432443
Register dst_reg = as_Register($dst$$reg);
24442444
Register src1_reg = as_Register($src1$$reg);
24452445
Register src2_reg = as_Register($src2$$reg);
2446-
__ corrected_idivl(dst_reg, src1_reg, src2_reg, false);
2446+
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ true);
2447+
%}
2448+
2449+
enc_class riscv_enc_divuw(iRegI dst, iRegI src1, iRegI src2) %{
2450+
C2_MacroAssembler _masm(&cbuf);
2451+
Register dst_reg = as_Register($dst$$reg);
2452+
Register src1_reg = as_Register($src1$$reg);
2453+
Register src2_reg = as_Register($src2$$reg);
2454+
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ false);
24472455
%}
24482456

24492457
enc_class riscv_enc_div(iRegI dst, iRegI src1, iRegI src2) %{
24502458
C2_MacroAssembler _masm(&cbuf);
24512459
Register dst_reg = as_Register($dst$$reg);
24522460
Register src1_reg = as_Register($src1$$reg);
24532461
Register src2_reg = as_Register($src2$$reg);
2454-
__ corrected_idivq(dst_reg, src1_reg, src2_reg, false);
2462+
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ true);
2463+
%}
2464+
2465+
enc_class riscv_enc_divu(iRegI dst, iRegI src1, iRegI src2) %{
2466+
C2_MacroAssembler _masm(&cbuf);
2467+
Register dst_reg = as_Register($dst$$reg);
2468+
Register src1_reg = as_Register($src1$$reg);
2469+
Register src2_reg = as_Register($src2$$reg);
2470+
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ false);
24552471
%}
24562472

24572473
enc_class riscv_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{
24582474
C2_MacroAssembler _masm(&cbuf);
24592475
Register dst_reg = as_Register($dst$$reg);
24602476
Register src1_reg = as_Register($src1$$reg);
24612477
Register src2_reg = as_Register($src2$$reg);
2462-
__ corrected_idivl(dst_reg, src1_reg, src2_reg, true);
2478+
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ true);
24632479
%}
24642480

24652481
enc_class riscv_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{
24662482
C2_MacroAssembler _masm(&cbuf);
24672483
Register dst_reg = as_Register($dst$$reg);
24682484
Register src1_reg = as_Register($src1$$reg);
24692485
Register src2_reg = as_Register($src2$$reg);
2470-
__ corrected_idivq(dst_reg, src1_reg, src2_reg, true);
2486+
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ true);
24712487
%}
24722488

24732489
enc_class riscv_enc_tail_call(iRegP jump_target) %{
@@ -6673,6 +6689,15 @@ instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
66736689
ins_pipe(idiv_reg_reg);
66746690
%}
66756691

6692+
instruct UdivI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
6693+
match(Set dst (UDivI src1 src2));
6694+
ins_cost(IDIVSI_COST);
6695+
format %{ "divuw $dst, $src1, $src2\t#@UdivI"%}
6696+
6697+
ins_encode(riscv_enc_divuw(dst, src1, src2));
6698+
ins_pipe(idiv_reg_reg);
6699+
%}
6700+
66766701
instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{
66776702
match(Set dst (URShiftI (RShiftI src1 div1) div2));
66786703
ins_cost(ALU_COST);
@@ -6695,6 +6720,16 @@ instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
66956720
ins_pipe(ldiv_reg_reg);
66966721
%}
66976722

6723+
instruct UdivL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
6724+
match(Set dst (UDivL src1 src2));
6725+
ins_cost(IDIVDI_COST);
6726+
6727+
format %{ "divu $dst, $src1, $src2\t#@UdivL" %}
6728+
6729+
ins_encode(riscv_enc_divu(dst, src1, src2));
6730+
ins_pipe(ldiv_reg_reg);
6731+
%}
6732+
66986733
instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{
66996734
match(Set dst (URShiftL (RShiftL src1 div1) div2));
67006735
ins_cost(ALU_COST);

src/hotspot/cpu/riscv/templateTable_riscv.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,7 @@ void TemplateTable::idiv() {
13181318
__ bind(no_div0);
13191319
__ pop_i(x11);
13201320
// x10 <== x11 idiv x10
1321-
__ corrected_idivl(x10, x11, x10, /* want_remainder */ false);
1321+
__ corrected_idivl(x10, x11, x10, /* want_remainder */ false, /* is_signed */ true);
13221322
}
13231323

13241324
void TemplateTable::irem() {
@@ -1331,7 +1331,7 @@ void TemplateTable::irem() {
13311331
__ bind(no_div0);
13321332
__ pop_i(x11);
13331333
// x10 <== x11 irem x10
1334-
__ corrected_idivl(x10, x11, x10, /* want_remainder */ true);
1334+
__ corrected_idivl(x10, x11, x10, /* want_remainder */ true, /* is_signed */ true);
13351335
}
13361336

13371337
void TemplateTable::lmul() {
@@ -1350,7 +1350,7 @@ void TemplateTable::ldiv() {
13501350
__ bind(no_div0);
13511351
__ pop_l(x11);
13521352
// x10 <== x11 ldiv x10
1353-
__ corrected_idivq(x10, x11, x10, /* want_remainder */ false);
1353+
__ corrected_idivq(x10, x11, x10, /* want_remainder */ false, /* is_signed */ true);
13541354
}
13551355

13561356
void TemplateTable::lrem() {
@@ -1363,7 +1363,7 @@ void TemplateTable::lrem() {
13631363
__ bind(no_div0);
13641364
__ pop_l(x11);
13651365
// x10 <== x11 lrem x10
1366-
__ corrected_idivq(x10, x11, x10, /* want_remainder */ true);
1366+
__ corrected_idivq(x10, x11, x10, /* want_remainder */ true, /* is_signed */ true);
13671367
}
13681368

13691369
void TemplateTable::lshl() {

test/hotspot/jtreg/compiler/intrinsics/TestIntegerUnsignedDivMod.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,8 @@
2323

2424
/**
2525
* @test
26-
* @summary Test x86_64 intrinsic for divideUnsigned() and remainderUnsigned() methods for Integer
27-
* @requires os.arch=="amd64" | os.arch=="x86_64"
26+
* @summary Test intrinsic for divideUnsigned() and remainderUnsigned() methods for Integer
27+
* @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="riscv64"
2828
* @library /test/lib /
2929
* @run driver compiler.intrinsics.TestIntegerUnsignedDivMod
3030
*/

test/hotspot/jtreg/compiler/intrinsics/TestLongUnsignedDivMod.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,8 @@
2323

2424
/**
2525
* @test
26-
* @summary Test x86_64 intrinsic for divideUnsigned() and remainderUnsigned() methods for Long
27-
* @requires os.arch=="amd64" | os.arch=="x86_64"
26+
* @summary Test intrinsic for divideUnsigned() and remainderUnsigned() methods for Long
27+
* @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="riscv64"
2828
* @library /test/lib /
2929
* @run driver compiler.intrinsics.TestLongUnsignedDivMod
3030
*/

0 commit comments

Comments
 (0)