8275167: x86 intrinsic for unsignedMultiplyHigh
Reviewed-by: kvn, sviswanathan
This commit is contained in:
parent
cea3f01046
commit
af7c56b85b
@ -8527,6 +8527,19 @@ instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
|
||||
ins_pipe(ialu_reg_reg_alu0);
|
||||
%}
|
||||
|
||||
instruct umulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst (UMulHiL src rax));
|
||||
effect(USE_KILL rax, KILL cr);
|
||||
|
||||
ins_cost(300);
|
||||
format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %}
|
||||
ins_encode %{
|
||||
__ mulq($src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg_alu0);
|
||||
%}
|
||||
|
||||
instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
|
||||
rFlagsReg cr)
|
||||
%{
|
||||
|
@ -140,6 +140,7 @@ class methodHandle;
|
||||
do_name(incrementExact_name,"incrementExact") \
|
||||
do_name(multiplyExact_name,"multiplyExact") \
|
||||
do_name(multiplyHigh_name,"multiplyHigh") \
|
||||
do_name(unsignedMultiplyHigh_name,"unsignedMultiplyHigh") \
|
||||
do_name(negateExact_name,"negateExact") \
|
||||
do_name(subtractExact_name,"subtractExact") \
|
||||
do_name(fma_name, "fma") \
|
||||
@ -173,6 +174,7 @@ class methodHandle;
|
||||
do_intrinsic(_multiplyExactI, java_lang_Math, multiplyExact_name, int2_int_signature, F_S) \
|
||||
do_intrinsic(_multiplyExactL, java_lang_Math, multiplyExact_name, long2_long_signature, F_S) \
|
||||
do_intrinsic(_multiplyHigh, java_lang_Math, multiplyHigh_name, long2_long_signature, F_S) \
|
||||
do_intrinsic(_unsignedMultiplyHigh, java_lang_Math, unsignedMultiplyHigh_name, long2_long_signature, F_S) \
|
||||
do_intrinsic(_negateExactI, java_lang_Math, negateExact_name, int_int_signature, F_S) \
|
||||
do_intrinsic(_negateExactL, java_lang_Math, negateExact_name, long_long_signature, F_S) \
|
||||
do_intrinsic(_subtractExactI, java_lang_Math, subtractExact_name, int2_int_signature, F_S) \
|
||||
|
@ -426,6 +426,9 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt
|
||||
case vmIntrinsics::_multiplyHigh:
|
||||
if (!Matcher::match_rule_supported(Op_MulHiL)) return false;
|
||||
break;
|
||||
case vmIntrinsics::_unsignedMultiplyHigh:
|
||||
if (!Matcher::match_rule_supported(Op_UMulHiL)) return false;
|
||||
break;
|
||||
case vmIntrinsics::_getCallerClass:
|
||||
if (vmClasses::reflect_CallerSensitive_klass() == NULL) return false;
|
||||
break;
|
||||
|
@ -238,6 +238,7 @@ macro(MoveD2L)
|
||||
macro(MulD)
|
||||
macro(MulF)
|
||||
macro(MulHiL)
|
||||
macro(UMulHiL)
|
||||
macro(MulI)
|
||||
macro(MulL)
|
||||
macro(Multi)
|
||||
|
@ -286,6 +286,7 @@ bool LibraryCallKit::try_to_inline(int predicate) {
|
||||
case vmIntrinsics::_multiplyExactI: return inline_math_multiplyExactI();
|
||||
case vmIntrinsics::_multiplyExactL: return inline_math_multiplyExactL();
|
||||
case vmIntrinsics::_multiplyHigh: return inline_math_multiplyHigh();
|
||||
case vmIntrinsics::_unsignedMultiplyHigh: return inline_math_unsignedMultiplyHigh();
|
||||
case vmIntrinsics::_negateExactI: return inline_math_negateExactI();
|
||||
case vmIntrinsics::_negateExactL: return inline_math_negateExactL();
|
||||
case vmIntrinsics::_subtractExactI: return inline_math_subtractExactI(false /* subtract */);
|
||||
@ -1867,6 +1868,11 @@ bool LibraryCallKit::inline_math_multiplyHigh() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LibraryCallKit::inline_math_unsignedMultiplyHigh() {
|
||||
set_result(_gvn.transform(new UMulHiLNode(argument(0), argument(2))));
|
||||
return true;
|
||||
}
|
||||
|
||||
Node*
|
||||
LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
|
||||
// These are the candidate return value:
|
||||
|
@ -210,6 +210,7 @@ class LibraryCallKit : public GraphKit {
|
||||
bool inline_math_multiplyExactI();
|
||||
bool inline_math_multiplyExactL();
|
||||
bool inline_math_multiplyHigh();
|
||||
bool inline_math_unsignedMultiplyHigh();
|
||||
bool inline_math_negateExactI();
|
||||
bool inline_math_negateExactL();
|
||||
bool inline_math_subtractExactI(bool is_decrement);
|
||||
|
@ -432,14 +432,26 @@ const Type *MulDNode::mul_ring(const Type *t0, const Type *t1) const {
|
||||
//=============================================================================
|
||||
//------------------------------Value------------------------------------------
|
||||
const Type* MulHiLNode::Value(PhaseGVN* phase) const {
|
||||
// Either input is TOP ==> the result is TOP
|
||||
const Type *t1 = phase->type( in(1) );
|
||||
const Type *t2 = phase->type( in(2) );
|
||||
const Type *bot = bottom_type();
|
||||
return MulHiValue(t1, t2, bot);
|
||||
}
|
||||
|
||||
const Type* UMulHiLNode::Value(PhaseGVN* phase) const {
|
||||
const Type *t1 = phase->type( in(1) );
|
||||
const Type *t2 = phase->type( in(2) );
|
||||
const Type *bot = bottom_type();
|
||||
return MulHiValue(t1, t2, bot);
|
||||
}
|
||||
|
||||
// A common routine used by UMulHiLNode and MulHiLNode
|
||||
const Type* MulHiValue(const Type *t1, const Type *t2, const Type *bot) {
|
||||
// Either input is TOP ==> the result is TOP
|
||||
if( t1 == Type::TOP ) return Type::TOP;
|
||||
if( t2 == Type::TOP ) return Type::TOP;
|
||||
|
||||
// Either input is BOTTOM ==> the result is the local BOTTOM
|
||||
const Type *bot = bottom_type();
|
||||
if( (t1 == bot) || (t2 == bot) ||
|
||||
(t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) )
|
||||
return bot;
|
||||
|
@ -154,6 +154,8 @@ public:
|
||||
};
|
||||
|
||||
//-------------------------------MulHiLNode------------------------------------
|
||||
const Type* MulHiValue(const Type *t1, const Type *t2, const Type *bot);
|
||||
|
||||
// Upper 64 bits of a 64 bit by 64 bit multiply
|
||||
class MulHiLNode : public Node {
|
||||
public:
|
||||
@ -162,6 +164,18 @@ public:
|
||||
virtual const Type* Value(PhaseGVN* phase) const;
|
||||
const Type *bottom_type() const { return TypeLong::LONG; }
|
||||
virtual uint ideal_reg() const { return Op_RegL; }
|
||||
friend const Type* MulHiValue(const Type *t1, const Type *t2, const Type *bot);
|
||||
};
|
||||
|
||||
// Upper 64 bits of a 64 bit by 64 bit unsigned multiply
|
||||
class UMulHiLNode : public Node {
|
||||
public:
|
||||
UMulHiLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {}
|
||||
virtual int Opcode() const;
|
||||
virtual const Type* Value(PhaseGVN* phase) const;
|
||||
const Type *bottom_type() const { return TypeLong::LONG; }
|
||||
virtual uint ideal_reg() const { return Op_RegL; }
|
||||
friend const Type* MulHiValue(const Type *t1, const Type *t2, const Type *bot);
|
||||
};
|
||||
|
||||
//------------------------------AndINode---------------------------------------
|
||||
|
@ -1670,6 +1670,7 @@
|
||||
declare_c2_type(MulFNode, MulNode) \
|
||||
declare_c2_type(MulDNode, MulNode) \
|
||||
declare_c2_type(MulHiLNode, Node) \
|
||||
declare_c2_type(UMulHiLNode, Node) \
|
||||
declare_c2_type(AndINode, MulINode) \
|
||||
declare_c2_type(AndLNode, MulLNode) \
|
||||
declare_c2_type(LShiftINode, Node) \
|
||||
|
@ -1390,6 +1390,7 @@ public final class Math {
|
||||
* @see #multiplyHigh
|
||||
* @since 18
|
||||
*/
|
||||
@IntrinsicCandidate
|
||||
public static long unsignedMultiplyHigh(long x, long y) {
|
||||
// Compute via multiplyHigh() to leverage the intrinsic
|
||||
long result = Math.multiplyHigh(x, y);
|
||||
|
@ -540,4 +540,9 @@ public class MathBench {
|
||||
return Math.ulp(float7);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public long unsignedMultiplyHighLongLong() {
|
||||
return Math.unsignedMultiplyHigh(long747, long13);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user