8285040: PPC64 intrinsics for divideUnsigned and remainderUnsigned methods in java.lang.Integer and java.lang.Long

Reviewed-by: kvn, lucy
This commit is contained in:
Martin Doerr 2022-04-21 16:00:28 +00:00
parent 73f3e17ea7
commit e955cacb91
4 changed files with 59 additions and 0 deletions

@ -445,6 +445,7 @@ class Assembler : public AbstractAssembler {
MULHD_OPCODE = (31u << OPCODE_SHIFT | 73u << 1), // XO-FORM
MULHDU_OPCODE = (31u << OPCODE_SHIFT | 9u << 1), // XO-FORM
DIVD_OPCODE = (31u << OPCODE_SHIFT | 489u << 1), // XO-FORM
DIVDU_OPCODE = (31u << OPCODE_SHIFT | 457u << 1), // XO-FORM
CNTLZD_OPCODE = (31u << OPCODE_SHIFT | 58u << XO_21_30_SHIFT), // X-FORM
CNTTZD_OPCODE = (31u << OPCODE_SHIFT | 570u << XO_21_30_SHIFT), // X-FORM
@ -1422,6 +1423,8 @@ class Assembler : public AbstractAssembler {
inline void divd_( Register d, Register a, Register b);
inline void divw( Register d, Register a, Register b);
inline void divw_( Register d, Register a, Register b);
inline void divdu( Register d, Register a, Register b);
inline void divdu_( Register d, Register a, Register b);
inline void divwu( Register d, Register a, Register b);
inline void divwu_( Register d, Register a, Register b);

@ -128,6 +128,8 @@ inline void Assembler::divd( Register d, Register a, Register b) { emit_int32(
inline void Assembler::divd_( Register d, Register a, Register b) { emit_int32(DIVD_OPCODE | rt(d) | ra(a) | rb(b) | oe(0) | rc(1)); }
inline void Assembler::divw( Register d, Register a, Register b) { emit_int32(DIVW_OPCODE | rt(d) | ra(a) | rb(b) | oe(0) | rc(0)); }
inline void Assembler::divw_( Register d, Register a, Register b) { emit_int32(DIVW_OPCODE | rt(d) | ra(a) | rb(b) | oe(0) | rc(1)); }
inline void Assembler::divdu( Register d, Register a, Register b) { emit_int32(DIVDU_OPCODE | rt(d) | ra(a) | rb(b) | oe(0) | rc(0)); }
inline void Assembler::divdu_( Register d, Register a, Register b) { emit_int32(DIVDU_OPCODE | rt(d) | ra(a) | rb(b) | oe(0) | rc(1)); }
inline void Assembler::divwu( Register d, Register a, Register b) { emit_int32(DIVWU_OPCODE | rt(d) | ra(a) | rb(b) | oe(0) | rc(0)); }
inline void Assembler::divwu_( Register d, Register a, Register b) { emit_int32(DIVWU_OPCODE | rt(d) | ra(a) | rb(b) | oe(0) | rc(1)); }

@ -9013,6 +9013,50 @@ instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
%}
%}
instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
match(Set dst (UDivI src1 src2));
format %{ "DIVWU $dst, $src1, $src2" %}
size(4);
ins_encode %{
__ divwu($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(pipe_class_default);
%}
instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
match(Set dst (UModI src1 src2));
expand %{
iRegIdst tmp1;
iRegIdst tmp2;
udivI_reg_reg(tmp1, src1, src2);
// Compute lower 32 bit result using signed instructions as suggested by ISA.
// Upper 32 bit will contain garbage.
mulI_reg_reg(tmp2, src2, tmp1);
subI_reg_reg(dst, src1, tmp2);
%}
%}
instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
match(Set dst (UDivL src1 src2));
format %{ "DIVDU $dst, $src1, $src2" %}
size(4);
ins_encode %{
__ divdu($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(pipe_class_default);
%}
instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
match(Set dst (UModL src1 src2));
expand %{
iRegLdst tmp1;
iRegLdst tmp2;
udivL_reg_reg(tmp1, src1, src2);
mulL_reg_reg(tmp2, src2, tmp1);
subL_reg_reg(dst, src1, tmp2);
%}
%}
// Integer Shift Instructions
// Register Shift Left

@ -3510,6 +3510,11 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
UDivModINode* divmod = UDivModINode::make(n);
d->subsume_by(divmod->div_proj(), this);
n->subsume_by(divmod->mod_proj(), this);
} else {
// replace a%b with a-((a/b)*b)
Node* mult = new MulINode(d, d->in(2));
Node* sub = new SubINode(d->in(1), mult);
n->subsume_by(sub, this);
}
}
}
@ -3525,6 +3530,11 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
UDivModLNode* divmod = UDivModLNode::make(n);
d->subsume_by(divmod->div_proj(), this);
n->subsume_by(divmod->mod_proj(), this);
} else {
// replace a%b with a-((a/b)*b)
Node* mult = new MulLNode(d, d->in(2));
Node* sub = new SubLNode(d->in(1), mult);
n->subsume_by(sub, this);
}
}
}