8282162: [vector] Optimize integral vector negation API
Reviewed-by: jiefu, psandoz, njian
This commit is contained in:
parent
bfd9c2b30f
commit
d06685680c
@ -4266,6 +4266,47 @@ instruct vsqrt2D(vecX dst, vecX src)
|
||||
|
||||
// --------------------------------- NEG --------------------------------------
|
||||
|
||||
instruct vnegID(vecD dst, vecD src)
|
||||
%{
|
||||
predicate(n->as_Vector()->length_in_bytes() < 16);
|
||||
match(Set dst (NegVI src));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "negr $dst, $src\t# vector (8B/4H/2S)" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
Assembler::SIMD_Arrangement size = __ esize2arrangement((unsigned)type2aelembytes(bt), false);
|
||||
__ negr(as_FloatRegister($dst$$reg), size, as_FloatRegister($src$$reg));
|
||||
%}
|
||||
ins_pipe(vunop_fp64);
|
||||
%}
|
||||
|
||||
instruct vnegIX(vecX dst, vecX src)
|
||||
%{
|
||||
predicate(n->as_Vector()->length_in_bytes() == 16);
|
||||
match(Set dst (NegVI src));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "negr $dst, $src\t# vector (16B/8H/4S)" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
Assembler::SIMD_Arrangement size = __ esize2arrangement((unsigned)type2aelembytes(bt), true);
|
||||
__ negr(as_FloatRegister($dst$$reg), size, as_FloatRegister($src$$reg));
|
||||
%}
|
||||
ins_pipe(vunop_fp128);
|
||||
%}
|
||||
|
||||
instruct vneg2L(vecX dst, vecX src)
|
||||
%{
|
||||
predicate(n->as_Vector()->length() == 2);
|
||||
match(Set dst (NegVL src));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "negr $dst,$src\t# vector (2D)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($dst$$reg), __ T2D,
|
||||
as_FloatRegister($src$$reg));
|
||||
%}
|
||||
ins_pipe(vunop_fp128);
|
||||
%}
|
||||
|
||||
instruct vneg2F(vecD dst, vecD src)
|
||||
%{
|
||||
predicate(n->as_Vector()->length() == 2);
|
||||
|
@ -1923,20 +1923,39 @@ VSQRT(fsqrt, 4, F, X, S)
|
||||
VSQRT(fsqrt, 2, D, X, D)
|
||||
|
||||
// --------------------------------- NEG --------------------------------------
|
||||
define(`VNEGI', `
|
||||
instruct vnegI$1(vec$1 dst, vec$1 src)
|
||||
%{
|
||||
predicate(n->as_Vector()->length_in_bytes() ifelse($1, D, <, ==) 16);
|
||||
match(Set dst (NegVI src));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "negr $dst, $src\t# vector ($2)" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
Assembler::SIMD_Arrangement size = __ esize2arrangement((unsigned)type2aelembytes(bt), ifelse($1, D, false, true));
|
||||
__ negr(as_FloatRegister($dst$$reg), size, as_FloatRegister($src$$reg));
|
||||
%}
|
||||
ins_pipe(vunop_fp`'ifelse($1, D, 64, 128));
|
||||
%}')dnl
|
||||
dnl $1 $2
|
||||
VNEGI(D, 8B/4H/2S)
|
||||
VNEGI(X, 16B/8H/4S)
|
||||
dnl
|
||||
define(`VNEG', `
|
||||
instruct vneg$2$3`'(vec$4 dst, vec$4 src)
|
||||
%{
|
||||
predicate(n->as_Vector()->length() == $2);
|
||||
match(Set dst (NegV$3 src));
|
||||
ins_cost(INSN_COST * 3);
|
||||
ins_cost(INSN_COST`'ifelse($3, L, `',` * 3'));
|
||||
format %{ "$1 $dst,$src\t# vector ($2$5)" %}
|
||||
ins_encode %{
|
||||
__ $1(as_FloatRegister($dst$$reg), __ T$2`'ifelse($5, L, D, $5),
|
||||
__ $1(as_FloatRegister($dst$$reg), __ T$2$5,
|
||||
as_FloatRegister($src$$reg));
|
||||
%}
|
||||
ins_pipe(vunop_fp`'ifelse($4, D, 64, 128));
|
||||
%}')dnl
|
||||
dnl $1 $2 $3 $4 $5
|
||||
VNEG(negr, 2, L, X, D)
|
||||
VNEG(fneg, 2, F, D, S)
|
||||
VNEG(fneg, 4, F, X, S)
|
||||
VNEG(fneg, 2, D, X, D)
|
||||
|
@ -1936,7 +1936,34 @@ instruct vmulD_masked(vReg dst_src1, vReg src2, pRegGov pg) %{
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// vector fneg
|
||||
// vector neg
|
||||
|
||||
instruct vnegI(vReg dst, vReg src) %{
|
||||
predicate(UseSVE > 0 &&
|
||||
!n->as_Vector()->is_predicated_vector());
|
||||
match(Set dst (NegVI src));
|
||||
ins_cost(SVE_COST);
|
||||
format %{ "sve_neg $dst, $src\t# vector (sve) (B/H/S)" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
__ sve_neg(as_FloatRegister($dst$$reg), __ elemType_to_regVariant(bt),
|
||||
ptrue, as_FloatRegister($src$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vnegL(vReg dst, vReg src) %{
|
||||
predicate(UseSVE > 0 &&
|
||||
!n->as_Vector()->is_predicated_vector());
|
||||
match(Set dst (NegVL src));
|
||||
ins_cost(SVE_COST);
|
||||
format %{ "sve_neg $dst, $src\t# vector (sve) (D)" %}
|
||||
ins_encode %{
|
||||
__ sve_neg(as_FloatRegister($dst$$reg), __ D,
|
||||
ptrue, as_FloatRegister($src$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vnegF(vReg dst, vReg src) %{
|
||||
predicate(UseSVE > 0 &&
|
||||
@ -1964,7 +1991,34 @@ instruct vnegD(vReg dst, vReg src) %{
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// vector fneg - predicated
|
||||
// vector neg - predicated
|
||||
|
||||
instruct vnegI_masked(vReg dst_src, pRegGov pg) %{
|
||||
predicate(UseSVE > 0);
|
||||
match(Set dst_src (NegVI dst_src pg));
|
||||
ins_cost(SVE_COST);
|
||||
format %{ "sve_neg $dst_src, $pg, $dst_src\t# vector (sve) (B/H/S)" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
__ sve_neg(as_FloatRegister($dst_src$$reg), __ elemType_to_regVariant(bt),
|
||||
as_PRegister($pg$$reg),
|
||||
as_FloatRegister($dst_src$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vnegL_masked(vReg dst_src, pRegGov pg) %{
|
||||
predicate(UseSVE > 0);
|
||||
match(Set dst_src (NegVL dst_src pg));
|
||||
ins_cost(SVE_COST);
|
||||
format %{ "sve_neg $dst_src, $pg, $dst_src\t# vector (sve) (D)" %}
|
||||
ins_encode %{
|
||||
__ sve_neg(as_FloatRegister($dst_src$$reg), __ D,
|
||||
as_PRegister($pg$$reg),
|
||||
as_FloatRegister($dst_src$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vnegF_masked(vReg dst_src, pRegGov pg) %{
|
||||
predicate(UseSVE > 0);
|
||||
|
@ -524,8 +524,10 @@ instruct $1(vReg dst, vReg src) %{
|
||||
match(Set dst ($2 src));
|
||||
ins_cost(SVE_COST);
|
||||
format %{ "$4 $dst, $src\t# vector (sve) ($3)" %}
|
||||
ins_encode %{
|
||||
__ $4(as_FloatRegister($dst$$reg), __ $3,
|
||||
ins_encode %{dnl
|
||||
ifelse($1, `vnegI', `
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);', `')
|
||||
__ $4(as_FloatRegister($dst$$reg), ifelse($1, `vnegI', `__ elemType_to_regVariant(bt)', `__ $3'),
|
||||
ptrue, as_FloatRegister($src$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
@ -548,8 +550,10 @@ instruct $1_masked(vReg dst_src, pRegGov pg) %{
|
||||
match(Set dst_src ($2 dst_src pg));
|
||||
ins_cost(SVE_COST);
|
||||
format %{ "$4 $dst_src, $pg, $dst_src\t# vector (sve) ($3)" %}
|
||||
ins_encode %{
|
||||
__ $4(as_FloatRegister($dst_src$$reg), __ $3,
|
||||
ins_encode %{dnl
|
||||
ifelse($1, `vnegI', `
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);', `')
|
||||
__ $4(as_FloatRegister($dst_src$$reg), ifelse($1, `vnegI', `__ elemType_to_regVariant(bt)', `__ $3'),
|
||||
as_PRegister($pg$$reg),
|
||||
as_FloatRegister($dst_src$$reg));
|
||||
%}
|
||||
@ -1091,11 +1095,15 @@ BINARY_OP_PREDICATE(vmulL, MulVL, D, sve_mul)
|
||||
BINARY_OP_PREDICATE(vmulF, MulVF, S, sve_fmul)
|
||||
BINARY_OP_PREDICATE(vmulD, MulVD, D, sve_fmul)
|
||||
|
||||
// vector fneg
|
||||
// vector neg
|
||||
UNARY_OP_TRUE_PREDICATE(vnegI, NegVI, B/H/S, sve_neg)
|
||||
UNARY_OP_TRUE_PREDICATE(vnegL, NegVL, D, sve_neg)
|
||||
UNARY_OP_TRUE_PREDICATE(vnegF, NegVF, S, sve_fneg)
|
||||
UNARY_OP_TRUE_PREDICATE(vnegD, NegVD, D, sve_fneg)
|
||||
|
||||
// vector fneg - predicated
|
||||
// vector neg - predicated
|
||||
UNARY_OP_PREDICATE(vnegI, NegVI, B/H/S, sve_neg)
|
||||
UNARY_OP_PREDICATE(vnegL, NegVL, D, sve_neg)
|
||||
UNARY_OP_PREDICATE(vnegF, NegVF, S, sve_fneg)
|
||||
UNARY_OP_PREDICATE(vnegD, NegVD, D, sve_fneg)
|
||||
|
||||
|
@ -4212,7 +4212,7 @@ bool MatchRule::is_vector() const {
|
||||
"CMoveVD", "CMoveVF",
|
||||
"DivVF","DivVD",
|
||||
"AbsVB","AbsVS","AbsVI","AbsVL","AbsVF","AbsVD",
|
||||
"NegVF","NegVD","NegVI",
|
||||
"NegVF","NegVD","NegVI","NegVL",
|
||||
"SqrtVD","SqrtVF",
|
||||
"AndV" ,"XorV" ,"OrV",
|
||||
"MaxV", "MinV",
|
||||
|
@ -386,6 +386,7 @@ macro(AbsVL)
|
||||
macro(AbsVF)
|
||||
macro(AbsVD)
|
||||
macro(NegVI)
|
||||
macro(NegVL)
|
||||
macro(NegVF)
|
||||
macro(NegVD)
|
||||
macro(SqrtVD)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Oracle 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
|
||||
@ -199,6 +199,16 @@ bool LibraryCallKit::arch_supports_vector(int sopc, int num_elem, BasicType type
|
||||
tty->print_cr(" ** Rejected vector op (%s,%s,%d) because architecture does not support variable vector shifts",
|
||||
NodeClassNames[sopc], type2name(type), num_elem);
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
} else if (VectorNode::is_vector_integral_negate(sopc)) {
|
||||
if (!VectorNode::is_vector_integral_negate_supported(sopc, num_elem, type, false)) {
|
||||
#ifndef PRODUCT
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** Rejected vector op (%s,%s,%d) because architecture does not support integral vector negate",
|
||||
NodeClassNames[sopc], type2name(type), num_elem);
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@ -277,8 +287,16 @@ bool LibraryCallKit::arch_supports_vector(int sopc, int num_elem, BasicType type
|
||||
}
|
||||
|
||||
if ((mask_use_type & VecMaskUsePred) != 0) {
|
||||
if (!Matcher::has_predicated_vectors() ||
|
||||
!Matcher::match_rule_supported_vector_masked(sopc, num_elem, type)) {
|
||||
bool is_supported = false;
|
||||
if (Matcher::has_predicated_vectors()) {
|
||||
if (VectorNode::is_vector_integral_negate(sopc)) {
|
||||
is_supported = VectorNode::is_vector_integral_negate_supported(sopc, num_elem, type, true);
|
||||
} else {
|
||||
is_supported = Matcher::match_rule_supported_vector_masked(sopc, num_elem, type);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_supported) {
|
||||
#ifndef PRODUCT
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr("Rejected vector mask predicate using (%s,%s,%d) because architecture does not support it",
|
||||
|
@ -135,7 +135,14 @@ int VectorNode::opcode(int sopc, BasicType bt) {
|
||||
case Op_AbsD:
|
||||
return (bt == T_DOUBLE ? Op_AbsVD : 0);
|
||||
case Op_NegI:
|
||||
return (bt == T_INT ? Op_NegVI : 0);
|
||||
switch (bt) {
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_INT: return Op_NegVI;
|
||||
default: return 0;
|
||||
}
|
||||
case Op_NegL:
|
||||
return (bt == T_LONG ? Op_NegVL : 0);
|
||||
case Op_NegF:
|
||||
return (bt == T_FLOAT ? Op_NegVF : 0);
|
||||
case Op_NegD:
|
||||
@ -275,6 +282,9 @@ bool VectorNode::implemented(int opc, uint vlen, BasicType bt) {
|
||||
if (VectorNode::is_vector_rotate(vopc)) {
|
||||
return is_vector_rotate_supported(vopc, vlen, bt);
|
||||
}
|
||||
if (VectorNode::is_vector_integral_negate(vopc)) {
|
||||
return is_vector_integral_negate_supported(vopc, vlen, bt, false);
|
||||
}
|
||||
return vopc > 0 && Matcher::match_rule_supported_vector(vopc, vlen, bt);
|
||||
}
|
||||
return false;
|
||||
@ -349,6 +359,38 @@ bool VectorNode::is_vector_rotate_supported(int vopc, uint vlen, BasicType bt) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether the architecture supports the vector negate instructions. If not, then check
|
||||
// whether the alternative vector nodes used to implement vector negation are supported.
|
||||
// Return false if neither of them is supported.
|
||||
bool VectorNode::is_vector_integral_negate_supported(int opc, uint vlen, BasicType bt, bool use_predicate) {
|
||||
if (!use_predicate) {
|
||||
// Check whether the NegVI/L is supported by the architecture.
|
||||
if (Matcher::match_rule_supported_vector(opc, vlen, bt)) {
|
||||
return true;
|
||||
}
|
||||
// Negate is implemented with "(SubVI/L (ReplicateI/L 0) src)", if NegVI/L is not supported.
|
||||
int sub_opc = (bt == T_LONG) ? Op_SubL : Op_SubI;
|
||||
if (Matcher::match_rule_supported_vector(VectorNode::opcode(sub_opc, bt), vlen, bt) &&
|
||||
Matcher::match_rule_supported_vector(VectorNode::replicate_opcode(bt), vlen, bt)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Check whether the predicated NegVI/L is supported by the architecture.
|
||||
if (Matcher::match_rule_supported_vector_masked(opc, vlen, bt)) {
|
||||
return true;
|
||||
}
|
||||
// Predicated negate is implemented with "(AddVI/L (XorV src (ReplicateI/L -1)) (ReplicateI/L 1))",
|
||||
// if predicated NegVI/L is not supported.
|
||||
int add_opc = (bt == T_LONG) ? Op_AddL : Op_AddI;
|
||||
if (Matcher::match_rule_supported_vector_masked(Op_XorV, vlen, bt) &&
|
||||
Matcher::match_rule_supported_vector_masked(VectorNode::opcode(add_opc, bt), vlen, bt) &&
|
||||
Matcher::match_rule_supported_vector(VectorNode::replicate_opcode(bt), vlen, bt)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VectorNode::is_shift_opcode(int opc) {
|
||||
switch (opc) {
|
||||
case Op_LShiftI:
|
||||
@ -536,6 +578,7 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, b
|
||||
case Op_AbsVL: return new AbsVLNode(n1, vt);
|
||||
|
||||
case Op_NegVI: return new NegVINode(n1, vt);
|
||||
case Op_NegVL: return new NegVLNode(n1, vt);
|
||||
case Op_NegVF: return new NegVFNode(n1, vt);
|
||||
case Op_NegVD: return new NegVDNode(n1, vt);
|
||||
|
||||
@ -667,6 +710,10 @@ bool VectorNode::is_vector_rotate(int opc) {
|
||||
}
|
||||
}
|
||||
|
||||
bool VectorNode::is_vector_integral_negate(int opc) {
|
||||
return opc == Op_NegVI || opc == Op_NegVL;
|
||||
}
|
||||
|
||||
bool VectorNode::is_vector_shift(int opc) {
|
||||
assert(opc > _last_machine_leaf && opc < _last_opcode, "invalid opcode");
|
||||
switch (opc) {
|
||||
@ -1541,6 +1588,69 @@ Node* VectorLongToMaskNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Generate other vector nodes to implement the masked/non-masked vector negation.
|
||||
Node* NegVNode::degenerate_integral_negate(PhaseGVN* phase, bool is_predicated) {
|
||||
const TypeVect* vt = vect_type();
|
||||
BasicType bt = vt->element_basic_type();
|
||||
uint vlen = length();
|
||||
|
||||
// Transformation for predicated NegVI/L
|
||||
if (is_predicated) {
|
||||
// (NegVI/L src m) ==> (AddVI/L (XorV src (ReplicateI/L -1) m) (ReplicateI/L 1) m)
|
||||
Node* const_minus_one = NULL;
|
||||
Node* const_one = NULL;
|
||||
int add_opc;
|
||||
if (bt == T_LONG) {
|
||||
const_minus_one = phase->longcon(-1L);
|
||||
const_one = phase->longcon(1L);
|
||||
add_opc = Op_AddL;
|
||||
} else {
|
||||
const_minus_one = phase->intcon(-1);
|
||||
const_one = phase->intcon(1);
|
||||
add_opc = Op_AddI;
|
||||
}
|
||||
const_minus_one = phase->transform(VectorNode::scalar2vector(const_minus_one, vlen, Type::get_const_basic_type(bt)));
|
||||
Node* xorv = VectorNode::make(Op_XorV, in(1), const_minus_one, vt);
|
||||
xorv->add_req(in(2));
|
||||
xorv->add_flag(Node::Flag_is_predicated_vector);
|
||||
phase->transform(xorv);
|
||||
const_one = phase->transform(VectorNode::scalar2vector(const_one, vlen, Type::get_const_basic_type(bt)));
|
||||
Node* addv = VectorNode::make(VectorNode::opcode(add_opc, bt), xorv, const_one, vt);
|
||||
addv->add_req(in(2));
|
||||
addv->add_flag(Node::Flag_is_predicated_vector);
|
||||
return addv;
|
||||
}
|
||||
|
||||
// NegVI/L ==> (SubVI/L (ReplicateI/L 0) src)
|
||||
Node* const_zero = NULL;
|
||||
int sub_opc;
|
||||
if (bt == T_LONG) {
|
||||
const_zero = phase->longcon(0L);
|
||||
sub_opc = Op_SubL;
|
||||
} else {
|
||||
const_zero = phase->intcon(0);
|
||||
sub_opc = Op_SubI;
|
||||
}
|
||||
const_zero = phase->transform(VectorNode::scalar2vector(const_zero, vlen, Type::get_const_basic_type(bt)));
|
||||
return VectorNode::make(VectorNode::opcode(sub_opc, bt), const_zero, in(1), vt);
|
||||
}
|
||||
|
||||
Node* NegVNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||
BasicType bt = vect_type()->element_basic_type();
|
||||
uint vlen = length();
|
||||
int opc = Opcode();
|
||||
if (is_vector_integral_negate(opc)) {
|
||||
if (is_predicated_vector()) {
|
||||
if (!Matcher::match_rule_supported_vector_masked(opc, vlen, bt)) {
|
||||
return degenerate_integral_negate(phase, true);
|
||||
}
|
||||
} else if (!Matcher::match_rule_supported_vector(opc, vlen, bt)) {
|
||||
return degenerate_integral_negate(phase, false);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void VectorBoxAllocateNode::dump_spec(outputStream *st) const {
|
||||
CallStaticJavaNode::dump_spec(st);
|
||||
|
@ -97,6 +97,7 @@ class VectorNode : public TypeNode {
|
||||
static bool is_roundopD(Node* n);
|
||||
static bool is_scalar_rotate(Node* n);
|
||||
static bool is_vector_rotate_supported(int opc, uint vlen, BasicType bt);
|
||||
static bool is_vector_integral_negate_supported(int opc, uint vlen, BasicType bt, bool use_predicate);
|
||||
static bool is_invariant_vector(Node* n);
|
||||
static bool is_all_ones_vector(Node* n);
|
||||
static bool is_vector_bitwise_not_pattern(Node* n);
|
||||
@ -109,6 +110,7 @@ class VectorNode : public TypeNode {
|
||||
static bool is_vector_shift(int opc);
|
||||
static bool is_vector_shift_count(int opc);
|
||||
static bool is_vector_rotate(int opc);
|
||||
static bool is_vector_integral_negate(int opc);
|
||||
|
||||
static bool is_vector_shift(Node* n) {
|
||||
return is_vector_shift(n->Opcode());
|
||||
@ -474,27 +476,47 @@ class AbsVDNode : public VectorNode {
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
//------------------------------NegVINode--------------------------------------
|
||||
// Vector Neg int
|
||||
class NegVINode : public VectorNode {
|
||||
//------------------------------NegVNode---------------------------------------
|
||||
// Vector Neg parent class (not for code generation).
|
||||
class NegVNode : public VectorNode {
|
||||
public:
|
||||
NegVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
|
||||
NegVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
|
||||
virtual int Opcode() const = 0;
|
||||
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||
|
||||
private:
|
||||
Node* degenerate_integral_negate(PhaseGVN* phase, bool is_predicated);
|
||||
};
|
||||
|
||||
//------------------------------NegVINode--------------------------------------
|
||||
// Vector Neg byte/short/int
|
||||
class NegVINode : public NegVNode {
|
||||
public:
|
||||
NegVINode(Node* in, const TypeVect* vt) : NegVNode(in, vt) {}
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
//------------------------------NegVLNode--------------------------------------
|
||||
// Vector Neg long
|
||||
class NegVLNode : public NegVNode {
|
||||
public:
|
||||
NegVLNode(Node* in, const TypeVect* vt) : NegVNode(in, vt) {}
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
//------------------------------NegVFNode--------------------------------------
|
||||
// Vector Neg float
|
||||
class NegVFNode : public VectorNode {
|
||||
class NegVFNode : public NegVNode {
|
||||
public:
|
||||
NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
|
||||
NegVFNode(Node* in, const TypeVect* vt) : NegVNode(in, vt) {}
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
//------------------------------NegVDNode--------------------------------------
|
||||
// Vector Neg double
|
||||
class NegVDNode : public VectorNode {
|
||||
class NegVDNode : public NegVNode {
|
||||
public:
|
||||
NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
|
||||
NegVDNode(Node* in, const TypeVect* vt) : NegVNode(in, vt) {}
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
|
@ -1757,9 +1757,11 @@
|
||||
declare_c2_type(MulVFNode, VectorNode) \
|
||||
declare_c2_type(MulReductionVFNode, ReductionNode) \
|
||||
declare_c2_type(MulVDNode, VectorNode) \
|
||||
declare_c2_type(NegVINode, VectorNode) \
|
||||
declare_c2_type(NegVFNode, VectorNode) \
|
||||
declare_c2_type(NegVDNode, VectorNode) \
|
||||
declare_c2_type(NegVNode, VectorNode) \
|
||||
declare_c2_type(NegVINode, NegVNode) \
|
||||
declare_c2_type(NegVLNode, NegVNode) \
|
||||
declare_c2_type(NegVFNode, NegVNode) \
|
||||
declare_c2_type(NegVDNode, NegVNode) \
|
||||
declare_c2_type(FmaVDNode, VectorNode) \
|
||||
declare_c2_type(FmaVFNode, VectorNode) \
|
||||
declare_c2_type(CMoveVFNode, VectorNode) \
|
||||
|
@ -573,9 +573,6 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
||||
}
|
||||
if (op == NOT) {
|
||||
return broadcast(-1).lanewise(XOR, this);
|
||||
} else if (op == NEG) {
|
||||
// FIXME: Support this in the JIT.
|
||||
return broadcast(0).lanewise(SUB, this);
|
||||
}
|
||||
}
|
||||
int opc = opCode(op);
|
||||
@ -604,8 +601,6 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
||||
}
|
||||
if (op == NOT) {
|
||||
return lanewise(XOR, broadcast(-1), m);
|
||||
} else if (op == NEG) {
|
||||
return lanewise(NOT, m).lanewise(ADD, broadcast(1), m);
|
||||
}
|
||||
}
|
||||
int opc = opCode(op);
|
||||
|
@ -573,9 +573,6 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
||||
}
|
||||
if (op == NOT) {
|
||||
return broadcast(-1).lanewise(XOR, this);
|
||||
} else if (op == NEG) {
|
||||
// FIXME: Support this in the JIT.
|
||||
return broadcast(0).lanewise(SUB, this);
|
||||
}
|
||||
}
|
||||
int opc = opCode(op);
|
||||
@ -604,8 +601,6 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
||||
}
|
||||
if (op == NOT) {
|
||||
return lanewise(XOR, broadcast(-1), m);
|
||||
} else if (op == NEG) {
|
||||
return lanewise(NOT, m).lanewise(ADD, broadcast(1), m);
|
||||
}
|
||||
}
|
||||
int opc = opCode(op);
|
||||
|
@ -531,9 +531,6 @@ public abstract class LongVector extends AbstractVector<Long> {
|
||||
}
|
||||
if (op == NOT) {
|
||||
return broadcast(-1).lanewise(XOR, this);
|
||||
} else if (op == NEG) {
|
||||
// FIXME: Support this in the JIT.
|
||||
return broadcast(0).lanewise(SUB, this);
|
||||
}
|
||||
}
|
||||
int opc = opCode(op);
|
||||
@ -562,8 +559,6 @@ public abstract class LongVector extends AbstractVector<Long> {
|
||||
}
|
||||
if (op == NOT) {
|
||||
return lanewise(XOR, broadcast(-1), m);
|
||||
} else if (op == NEG) {
|
||||
return lanewise(NOT, m).lanewise(ADD, broadcast(1), m);
|
||||
}
|
||||
}
|
||||
int opc = opCode(op);
|
||||
|
@ -573,9 +573,6 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
||||
}
|
||||
if (op == NOT) {
|
||||
return broadcast(-1).lanewise(XOR, this);
|
||||
} else if (op == NEG) {
|
||||
// FIXME: Support this in the JIT.
|
||||
return broadcast(0).lanewise(SUB, this);
|
||||
}
|
||||
}
|
||||
int opc = opCode(op);
|
||||
@ -604,8 +601,6 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
||||
}
|
||||
if (op == NOT) {
|
||||
return lanewise(XOR, broadcast(-1), m);
|
||||
} else if (op == NEG) {
|
||||
return lanewise(NOT, m).lanewise(ADD, broadcast(1), m);
|
||||
}
|
||||
}
|
||||
int opc = opCode(op);
|
||||
|
@ -596,9 +596,6 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
||||
#if[BITWISE]
|
||||
if (op == NOT) {
|
||||
return broadcast(-1).lanewise(XOR, this);
|
||||
} else if (op == NEG) {
|
||||
// FIXME: Support this in the JIT.
|
||||
return broadcast(0).lanewise(SUB, this);
|
||||
}
|
||||
#end[BITWISE]
|
||||
}
|
||||
@ -629,8 +626,6 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
||||
#if[BITWISE]
|
||||
if (op == NOT) {
|
||||
return lanewise(XOR, broadcast(-1), m);
|
||||
} else if (op == NEG) {
|
||||
return lanewise(NOT, m).lanewise(ADD, broadcast(1), m);
|
||||
}
|
||||
#end[BITWISE]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user