Skip to content

Commit ac760dd

Browse files
author
Hamlin Li
committed
8352423: RISC-V: simplify DivI/L ModI/L
Reviewed-by: fyang, luhenry, rehn
1 parent d1cf232 commit ac760dd

File tree

6 files changed

+40
-153
lines changed

6 files changed

+40
-153
lines changed

src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,11 @@ void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right,
8585
}
8686
} else {
8787
Register rreg = right->as_register();
88-
__ corrected_idivl(dreg, lreg, rreg, is_irem, /* is_signed */ true);
88+
if (is_irem) {
89+
__ remw(dreg, lreg, rreg);
90+
} else {
91+
__ divw(dreg, lreg, rreg);
92+
}
8993
}
9094
}
9195

@@ -171,12 +175,8 @@ void LIR_Assembler::arith_op_double_cpu(LIR_Code code, LIR_Opr left, LIR_Opr rig
171175
case lir_add: __ add(dest->as_register_lo(), lreg_lo, rreg_lo); break;
172176
case lir_sub: __ sub(dest->as_register_lo(), lreg_lo, rreg_lo); break;
173177
case lir_mul: __ mul(dest->as_register_lo(), lreg_lo, rreg_lo); break;
174-
case lir_div: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo,
175-
/* want_remainder */ false, /* is_signed */ true);
176-
break;
177-
case lir_rem: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo,
178-
/* want_remainder */ true, /* is_signed */ true);
179-
break;
178+
case lir_div: __ div(dest->as_register_lo(), lreg_lo, rreg_lo); break;
179+
case lir_rem: __ rem(dest->as_register_lo(), lreg_lo, rreg_lo); break;
180180
default:
181181
ShouldNotReachHere();
182182
}

src/hotspot/cpu/riscv/macroAssembler_riscv.cpp

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3346,71 +3346,6 @@ void MacroAssembler::store_heap_oop_null(Address dst) {
33463346
access_store_at(T_OBJECT, IN_HEAP, dst, noreg, noreg, noreg, noreg);
33473347
}
33483348

3349-
int MacroAssembler::corrected_idivl(Register result, Register rs1, Register rs2,
3350-
bool want_remainder, bool is_signed)
3351-
{
3352-
// Full implementation of Java idiv and irem. The function
3353-
// returns the (pc) offset of the div instruction - may be needed
3354-
// for implicit exceptions.
3355-
//
3356-
// input : rs1: dividend
3357-
// rs2: divisor
3358-
//
3359-
// result: either
3360-
// quotient (= rs1 idiv rs2)
3361-
// remainder (= rs1 irem rs2)
3362-
3363-
3364-
int idivl_offset = offset();
3365-
if (!want_remainder) {
3366-
if (is_signed) {
3367-
divw(result, rs1, rs2);
3368-
} else {
3369-
divuw(result, rs1, rs2);
3370-
}
3371-
} else {
3372-
// result = rs1 % rs2;
3373-
if (is_signed) {
3374-
remw(result, rs1, rs2);
3375-
} else {
3376-
remuw(result, rs1, rs2);
3377-
}
3378-
}
3379-
return idivl_offset;
3380-
}
3381-
3382-
int MacroAssembler::corrected_idivq(Register result, Register rs1, Register rs2,
3383-
bool want_remainder, bool is_signed)
3384-
{
3385-
// Full implementation of Java ldiv and lrem. The function
3386-
// returns the (pc) offset of the div instruction - may be needed
3387-
// for implicit exceptions.
3388-
//
3389-
// input : rs1: dividend
3390-
// rs2: divisor
3391-
//
3392-
// result: either
3393-
// quotient (= rs1 idiv rs2)
3394-
// remainder (= rs1 irem rs2)
3395-
3396-
int idivq_offset = offset();
3397-
if (!want_remainder) {
3398-
if (is_signed) {
3399-
div(result, rs1, rs2);
3400-
} else {
3401-
divu(result, rs1, rs2);
3402-
}
3403-
} else {
3404-
// result = rs1 % rs2;
3405-
if (is_signed) {
3406-
rem(result, rs1, rs2);
3407-
} else {
3408-
remu(result, rs1, rs2);
3409-
}
3410-
}
3411-
return idivq_offset;
3412-
}
3413-
34143349
// Look up the method for a megamorphic invokeinterface call.
34153350
// The target method is determined by <intf_klass, itable_index>.
34163351
// The receiver klass is in recv_klass.

src/hotspot/cpu/riscv/macroAssembler_riscv.hpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,6 @@ class MacroAssembler: public Assembler {
242242
static bool needs_explicit_null_check(intptr_t offset);
243243
static bool uses_implicit_null_check(void* address);
244244

245-
// idiv variant which deals with MINLONG as dividend and -1 as divisor
246-
int corrected_idivl(Register result, Register rs1, Register rs2,
247-
bool want_remainder, bool is_signed);
248-
int corrected_idivq(Register result, Register rs1, Register rs2,
249-
bool want_remainder, bool is_signed);
250-
251245
// interface method calling
252246
void lookup_interface_method(Register recv_klass,
253247
Register intf_klass,

src/hotspot/cpu/riscv/riscv.ad

Lines changed: 24 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,64 +2485,6 @@ encode %{
24852485
}
24862486
%}
24872487

2488-
// arithmetic encodings
2489-
2490-
enc_class riscv_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{
2491-
Register dst_reg = as_Register($dst$$reg);
2492-
Register src1_reg = as_Register($src1$$reg);
2493-
Register src2_reg = as_Register($src2$$reg);
2494-
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ true);
2495-
%}
2496-
2497-
enc_class riscv_enc_divuw(iRegI dst, iRegI src1, iRegI src2) %{
2498-
Register dst_reg = as_Register($dst$$reg);
2499-
Register src1_reg = as_Register($src1$$reg);
2500-
Register src2_reg = as_Register($src2$$reg);
2501-
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ false);
2502-
%}
2503-
2504-
enc_class riscv_enc_div(iRegI dst, iRegI src1, iRegI src2) %{
2505-
Register dst_reg = as_Register($dst$$reg);
2506-
Register src1_reg = as_Register($src1$$reg);
2507-
Register src2_reg = as_Register($src2$$reg);
2508-
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ true);
2509-
%}
2510-
2511-
enc_class riscv_enc_divu(iRegI dst, iRegI src1, iRegI src2) %{
2512-
Register dst_reg = as_Register($dst$$reg);
2513-
Register src1_reg = as_Register($src1$$reg);
2514-
Register src2_reg = as_Register($src2$$reg);
2515-
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ false);
2516-
%}
2517-
2518-
enc_class riscv_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{
2519-
Register dst_reg = as_Register($dst$$reg);
2520-
Register src1_reg = as_Register($src1$$reg);
2521-
Register src2_reg = as_Register($src2$$reg);
2522-
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ true);
2523-
%}
2524-
2525-
enc_class riscv_enc_moduw(iRegI dst, iRegI src1, iRegI src2) %{
2526-
Register dst_reg = as_Register($dst$$reg);
2527-
Register src1_reg = as_Register($src1$$reg);
2528-
Register src2_reg = as_Register($src2$$reg);
2529-
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ false);
2530-
%}
2531-
2532-
enc_class riscv_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{
2533-
Register dst_reg = as_Register($dst$$reg);
2534-
Register src1_reg = as_Register($src1$$reg);
2535-
Register src2_reg = as_Register($src2$$reg);
2536-
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ true);
2537-
%}
2538-
2539-
enc_class riscv_enc_modu(iRegI dst, iRegI src1, iRegI src2) %{
2540-
Register dst_reg = as_Register($dst$$reg);
2541-
Register src1_reg = as_Register($src1$$reg);
2542-
Register src2_reg = as_Register($src2$$reg);
2543-
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ false);
2544-
%}
2545-
25462488
enc_class riscv_enc_tail_call(iRegP jump_target) %{
25472489
Register target_reg = as_Register($jump_target$$reg);
25482490
__ jr(target_reg);
@@ -6763,7 +6705,9 @@ instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
67636705
ins_cost(IDIVSI_COST);
67646706
format %{ "divw $dst, $src1, $src2\t#@divI"%}
67656707

6766-
ins_encode(riscv_enc_divw(dst, src1, src2));
6708+
ins_encode %{
6709+
__ divw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
6710+
%}
67676711
ins_pipe(idiv_reg_reg);
67686712
%}
67696713

@@ -6772,7 +6716,9 @@ instruct UdivI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
67726716
ins_cost(IDIVSI_COST);
67736717
format %{ "divuw $dst, $src1, $src2\t#@UdivI"%}
67746718

6775-
ins_encode(riscv_enc_divuw(dst, src1, src2));
6719+
ins_encode %{
6720+
__ divuw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
6721+
%}
67766722
ins_pipe(idiv_reg_reg);
67776723
%}
67786724

@@ -6794,7 +6740,9 @@ instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
67946740
ins_cost(IDIVDI_COST);
67956741
format %{ "div $dst, $src1, $src2\t#@divL" %}
67966742

6797-
ins_encode(riscv_enc_div(dst, src1, src2));
6743+
ins_encode %{
6744+
__ div(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
6745+
%}
67986746
ins_pipe(ldiv_reg_reg);
67996747
%}
68006748

@@ -6804,7 +6752,9 @@ instruct UdivL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
68046752

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

6807-
ins_encode(riscv_enc_divu(dst, src1, src2));
6755+
ins_encode %{
6756+
__ divu(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
6757+
%}
68086758
ins_pipe(ldiv_reg_reg);
68096759
%}
68106760

@@ -6826,7 +6776,9 @@ instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
68266776
ins_cost(IDIVSI_COST);
68276777
format %{ "remw $dst, $src1, $src2\t#@modI" %}
68286778

6829-
ins_encode(riscv_enc_modw(dst, src1, src2));
6779+
ins_encode %{
6780+
__ remw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
6781+
%}
68306782
ins_pipe(ialu_reg_reg);
68316783
%}
68326784

@@ -6835,7 +6787,9 @@ instruct UmodI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
68356787
ins_cost(IDIVSI_COST);
68366788
format %{ "remuw $dst, $src1, $src2\t#@UmodI" %}
68376789

6838-
ins_encode(riscv_enc_moduw(dst, src1, src2));
6790+
ins_encode %{
6791+
__ remuw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
6792+
%}
68396793
ins_pipe(ialu_reg_reg);
68406794
%}
68416795

@@ -6846,7 +6800,9 @@ instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
68466800
ins_cost(IDIVDI_COST);
68476801
format %{ "rem $dst, $src1, $src2\t#@modL" %}
68486802

6849-
ins_encode(riscv_enc_mod(dst, src1, src2));
6803+
ins_encode %{
6804+
__ rem(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
6805+
%}
68506806
ins_pipe(ialu_reg_reg);
68516807
%}
68526808

@@ -6855,7 +6811,9 @@ instruct UmodL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
68556811
ins_cost(IDIVDI_COST);
68566812
format %{ "remu $dst, $src1, $src2\t#@UmodL" %}
68576813

6858-
ins_encode(riscv_enc_modu(dst, src1, src2));
6814+
ins_encode %{
6815+
__ remu(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
6816+
%}
68596817
ins_pipe(ialu_reg_reg);
68606818
%}
68616819

src/hotspot/cpu/riscv/templateTable_riscv.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ void TemplateTable::idiv() {
13241324
__ bind(no_div0);
13251325
__ pop_i(x11);
13261326
// x10 <== x11 idiv x10
1327-
__ corrected_idivl(x10, x11, x10, /* want_remainder */ false, /* is_signed */ true);
1327+
__ divw(x10, x11, x10);
13281328
}
13291329

13301330
void TemplateTable::irem() {
@@ -1337,7 +1337,7 @@ void TemplateTable::irem() {
13371337
__ bind(no_div0);
13381338
__ pop_i(x11);
13391339
// x10 <== x11 irem x10
1340-
__ corrected_idivl(x10, x11, x10, /* want_remainder */ true, /* is_signed */ true);
1340+
__ remw(x10, x11, x10);
13411341
}
13421342

13431343
void TemplateTable::lmul() {
@@ -1356,7 +1356,7 @@ void TemplateTable::ldiv() {
13561356
__ bind(no_div0);
13571357
__ pop_l(x11);
13581358
// x10 <== x11 ldiv x10
1359-
__ corrected_idivq(x10, x11, x10, /* want_remainder */ false, /* is_signed */ true);
1359+
__ div(x10, x11, x10);
13601360
}
13611361

13621362
void TemplateTable::lrem() {
@@ -1369,7 +1369,7 @@ void TemplateTable::lrem() {
13691369
__ bind(no_div0);
13701370
__ pop_l(x11);
13711371
// x10 <== x11 lrem x10
1372-
__ corrected_idivq(x10, x11, x10, /* want_remainder */ true, /* is_signed */ true);
1372+
__ rem(x10, x11, x10);
13731373
}
13741374

13751375
void TemplateTable::lshl() {

test/hotspot/jtreg/compiler/c2/TestDivModNodes.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024 Red Hat and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2024, 2025, Red Hat 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
@@ -68,7 +68,7 @@ private static long nextNonZeroLong() {
6868
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"x64", "true"},
6969
counts = {IRNode.DIV_MOD_I, "1"},
7070
failOn = {IRNode.DIV_I, IRNode.MOD_I})
71-
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"aarch64", "true"},
71+
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatformOr = {"aarch64", "true", "riscv64", "true"},
7272
counts = {IRNode.DIV_I, "1", IRNode.MUL_I, "1", IRNode.SUB_I, "1"},
7373
failOn = {IRNode.MOD_I})
7474
@IR(applyIf = {"UseDivMod", "false"},
@@ -94,7 +94,7 @@ private static void runSignedIntDivMod() {
9494
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"x64", "true"},
9595
counts = {IRNode.DIV_MOD_L, "1"},
9696
failOn = {IRNode.DIV_L, IRNode.MOD_L})
97-
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"aarch64", "true"},
97+
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatformOr = {"aarch64", "true", "riscv64", "true"},
9898
counts = {IRNode.DIV_L, "1", IRNode.MUL_L, "1", IRNode.SUB_L, "1"},
9999
failOn = {IRNode.MOD_L})
100100
@IR(applyIf = {"UseDivMod", "false"},
@@ -119,7 +119,7 @@ private static void runSignedLongDivMod() {
119119
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"x64", "true"},
120120
counts = {IRNode.UDIV_MOD_I, "1"},
121121
failOn = {IRNode.UDIV_I, IRNode.UMOD_I})
122-
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"aarch64", "true"},
122+
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatformOr = {"aarch64", "true", "riscv64", "true"},
123123
counts = {IRNode.UDIV_I, "1", IRNode.MUL_I, "1", IRNode.SUB_I, "1"},
124124
failOn = {IRNode.UMOD_I})
125125
@IR(applyIf = {"UseDivMod", "false"},
@@ -144,7 +144,7 @@ private static void runUnsignedIntDivMod() {
144144
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"x64", "true"},
145145
counts = {IRNode.UDIV_MOD_L, "1"},
146146
failOn = {IRNode.UDIV_L, IRNode.UMOD_L})
147-
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"aarch64", "true"},
147+
@IR(applyIf = {"UseDivMod", "true"}, applyIfPlatformOr = {"aarch64", "true", "riscv64", "true"},
148148
counts = {IRNode.UDIV_L, "1", IRNode.MUL_L, "1", IRNode.SUB_L, "1"},
149149
failOn = {IRNode.MOD_L})
150150
@IR(applyIf = {"UseDivMod", "false"},

0 commit comments

Comments
 (0)