diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp index f84c44d6fea9b..6d53282bba55c 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp @@ -85,7 +85,11 @@ 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, /* is_signed */ true); + if (is_irem) { + __ remw(dreg, lreg, rreg); + } else { + __ divw(dreg, lreg, rreg); + } } } @@ -171,12 +175,8 @@ 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, - /* 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; + case lir_div: __ div(dest->as_register_lo(), lreg_lo, rreg_lo); break; + case lir_rem: __ rem(dest->as_register_lo(), lreg_lo, rreg_lo); break; default: ShouldNotReachHere(); } diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index d3daef7664d04..ee018f950913f 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -3346,71 +3346,6 @@ void MacroAssembler::store_heap_oop_null(Address dst) { access_store_at(T_OBJECT, IN_HEAP, dst, noreg, noreg, noreg, noreg); } -int MacroAssembler::corrected_idivl(Register result, Register rs1, Register rs2, - 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 - // for implicit exceptions. - // - // input : rs1: dividend - // rs2: divisor - // - // result: either - // quotient (= rs1 idiv rs2) - // remainder (= rs1 irem rs2) - - - int idivl_offset = offset(); - if (!want_remainder) { - if (is_signed) { - divw(result, rs1, rs2); - } else { - divuw(result, rs1, rs2); - } - } else { - // result = rs1 % rs2; - if (is_signed) { - remw(result, rs1, rs2); - } else { - remuw(result, rs1, rs2); - } - } - return idivl_offset; -} - -int MacroAssembler::corrected_idivq(Register result, Register rs1, Register rs2, - 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 - // for implicit exceptions. - // - // input : rs1: dividend - // rs2: divisor - // - // result: either - // quotient (= rs1 idiv rs2) - // remainder (= rs1 irem rs2) - - int idivq_offset = offset(); - if (!want_remainder) { - if (is_signed) { - div(result, rs1, rs2); - } else { - divu(result, rs1, rs2); - } - } else { - // result = rs1 % rs2; - if (is_signed) { - rem(result, rs1, rs2); - } else { - remu(result, rs1, rs2); - } - } - return idivq_offset; -} - // Look up the method for a megamorphic invokeinterface call. // The target method is determined by . // The receiver klass is in recv_klass. diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index f5dd4025185c2..e559292cfd650 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -242,12 +242,6 @@ class MacroAssembler: public Assembler { static bool needs_explicit_null_check(intptr_t offset); static bool uses_implicit_null_check(void* address); - // 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 is_signed); - int corrected_idivq(Register result, Register rs1, Register rs2, - bool want_remainder, bool is_signed); - // interface method calling void lookup_interface_method(Register recv_klass, Register intf_klass, diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index eb202f14ba1a2..25cea0d40c6d8 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -2485,64 +2485,6 @@ encode %{ } %} - // arithmetic encodings - - enc_class riscv_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ - 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 */ true); - %} - - enc_class riscv_enc_divuw(iRegI dst, iRegI src1, iRegI src2) %{ - 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) %{ - 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 */ true); - %} - - enc_class riscv_enc_divu(iRegI dst, iRegI src1, iRegI src2) %{ - 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) %{ - 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 */ true, /* is_signed */ true); - %} - - enc_class riscv_enc_moduw(iRegI dst, iRegI src1, iRegI src2) %{ - 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 */ true, /* is_signed */ false); - %} - - enc_class riscv_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ - 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 */ true, /* is_signed */ true); - %} - - enc_class riscv_enc_modu(iRegI dst, iRegI src1, iRegI src2) %{ - 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 */ true, /* is_signed */ false); - %} - enc_class riscv_enc_tail_call(iRegP jump_target) %{ Register target_reg = as_Register($jump_target$$reg); __ jr(target_reg); @@ -6763,7 +6705,9 @@ instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ ins_cost(IDIVSI_COST); format %{ "divw $dst, $src1, $src2\t#@divI"%} - ins_encode(riscv_enc_divw(dst, src1, src2)); + ins_encode %{ + __ divw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg)); + %} ins_pipe(idiv_reg_reg); %} @@ -6772,7 +6716,9 @@ instruct UdivI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ ins_cost(IDIVSI_COST); format %{ "divuw $dst, $src1, $src2\t#@UdivI"%} - ins_encode(riscv_enc_divuw(dst, src1, src2)); + ins_encode %{ + __ divuw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg)); + %} ins_pipe(idiv_reg_reg); %} @@ -6794,7 +6740,9 @@ instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ ins_cost(IDIVDI_COST); format %{ "div $dst, $src1, $src2\t#@divL" %} - ins_encode(riscv_enc_div(dst, src1, src2)); + ins_encode %{ + __ div(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg)); + %} ins_pipe(ldiv_reg_reg); %} @@ -6804,7 +6752,9 @@ instruct UdivL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ format %{ "divu $dst, $src1, $src2\t#@UdivL" %} - ins_encode(riscv_enc_divu(dst, src1, src2)); + ins_encode %{ + __ divu(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg)); + %} ins_pipe(ldiv_reg_reg); %} @@ -6826,7 +6776,9 @@ instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ ins_cost(IDIVSI_COST); format %{ "remw $dst, $src1, $src2\t#@modI" %} - ins_encode(riscv_enc_modw(dst, src1, src2)); + ins_encode %{ + __ remw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg)); + %} ins_pipe(ialu_reg_reg); %} @@ -6835,7 +6787,9 @@ instruct UmodI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ ins_cost(IDIVSI_COST); format %{ "remuw $dst, $src1, $src2\t#@UmodI" %} - ins_encode(riscv_enc_moduw(dst, src1, src2)); + ins_encode %{ + __ remuw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg)); + %} ins_pipe(ialu_reg_reg); %} @@ -6846,7 +6800,9 @@ instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ ins_cost(IDIVDI_COST); format %{ "rem $dst, $src1, $src2\t#@modL" %} - ins_encode(riscv_enc_mod(dst, src1, src2)); + ins_encode %{ + __ rem(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg)); + %} ins_pipe(ialu_reg_reg); %} @@ -6855,7 +6811,9 @@ instruct UmodL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ ins_cost(IDIVDI_COST); format %{ "remu $dst, $src1, $src2\t#@UmodL" %} - ins_encode(riscv_enc_modu(dst, src1, src2)); + ins_encode %{ + __ remu(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg)); + %} ins_pipe(ialu_reg_reg); %} diff --git a/src/hotspot/cpu/riscv/templateTable_riscv.cpp b/src/hotspot/cpu/riscv/templateTable_riscv.cpp index cb4ded3c330b6..216cfdeed7930 100644 --- a/src/hotspot/cpu/riscv/templateTable_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateTable_riscv.cpp @@ -1324,7 +1324,7 @@ void TemplateTable::idiv() { __ bind(no_div0); __ pop_i(x11); // x10 <== x11 idiv x10 - __ corrected_idivl(x10, x11, x10, /* want_remainder */ false, /* is_signed */ true); + __ divw(x10, x11, x10); } void TemplateTable::irem() { @@ -1337,7 +1337,7 @@ void TemplateTable::irem() { __ bind(no_div0); __ pop_i(x11); // x10 <== x11 irem x10 - __ corrected_idivl(x10, x11, x10, /* want_remainder */ true, /* is_signed */ true); + __ remw(x10, x11, x10); } void TemplateTable::lmul() { @@ -1356,7 +1356,7 @@ void TemplateTable::ldiv() { __ bind(no_div0); __ pop_l(x11); // x10 <== x11 ldiv x10 - __ corrected_idivq(x10, x11, x10, /* want_remainder */ false, /* is_signed */ true); + __ div(x10, x11, x10); } void TemplateTable::lrem() { @@ -1369,7 +1369,7 @@ void TemplateTable::lrem() { __ bind(no_div0); __ pop_l(x11); // x10 <== x11 lrem x10 - __ corrected_idivq(x10, x11, x10, /* want_remainder */ true, /* is_signed */ true); + __ rem(x10, x11, x10); } void TemplateTable::lshl() { diff --git a/test/hotspot/jtreg/compiler/c2/TestDivModNodes.java b/test/hotspot/jtreg/compiler/c2/TestDivModNodes.java index be7cf0a383661..3fdc37f3f3282 100644 --- a/test/hotspot/jtreg/compiler/c2/TestDivModNodes.java +++ b/test/hotspot/jtreg/compiler/c2/TestDivModNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Red Hat and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Red Hat 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 @@ -68,7 +68,7 @@ private static long nextNonZeroLong() { @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"x64", "true"}, counts = {IRNode.DIV_MOD_I, "1"}, failOn = {IRNode.DIV_I, IRNode.MOD_I}) - @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"aarch64", "true"}, + @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatformOr = {"aarch64", "true", "riscv64", "true"}, counts = {IRNode.DIV_I, "1", IRNode.MUL_I, "1", IRNode.SUB_I, "1"}, failOn = {IRNode.MOD_I}) @IR(applyIf = {"UseDivMod", "false"}, @@ -94,7 +94,7 @@ private static void runSignedIntDivMod() { @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"x64", "true"}, counts = {IRNode.DIV_MOD_L, "1"}, failOn = {IRNode.DIV_L, IRNode.MOD_L}) - @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"aarch64", "true"}, + @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatformOr = {"aarch64", "true", "riscv64", "true"}, counts = {IRNode.DIV_L, "1", IRNode.MUL_L, "1", IRNode.SUB_L, "1"}, failOn = {IRNode.MOD_L}) @IR(applyIf = {"UseDivMod", "false"}, @@ -119,7 +119,7 @@ private static void runSignedLongDivMod() { @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"x64", "true"}, counts = {IRNode.UDIV_MOD_I, "1"}, failOn = {IRNode.UDIV_I, IRNode.UMOD_I}) - @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"aarch64", "true"}, + @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatformOr = {"aarch64", "true", "riscv64", "true"}, counts = {IRNode.UDIV_I, "1", IRNode.MUL_I, "1", IRNode.SUB_I, "1"}, failOn = {IRNode.UMOD_I}) @IR(applyIf = {"UseDivMod", "false"}, @@ -144,7 +144,7 @@ private static void runUnsignedIntDivMod() { @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"x64", "true"}, counts = {IRNode.UDIV_MOD_L, "1"}, failOn = {IRNode.UDIV_L, IRNode.UMOD_L}) - @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatform = {"aarch64", "true"}, + @IR(applyIf = {"UseDivMod", "true"}, applyIfPlatformOr = {"aarch64", "true", "riscv64", "true"}, counts = {IRNode.UDIV_L, "1", IRNode.MUL_L, "1", IRNode.SUB_L, "1"}, failOn = {IRNode.MOD_L}) @IR(applyIf = {"UseDivMod", "false"},