Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8258932: AArch64: Enhance floating-point Min/MaxReductionV with fminp…
…/fmaxp

Reviewed-by: aph
  • Loading branch information
Dong Bo authored and Fei Yang committed Jan 12, 2021
1 parent 4c75d14 commit ccac7aaea380bc36c8dd0fe6e724c964489eeb6a
Show file tree
Hide file tree
Showing 7 changed files with 565 additions and 432 deletions.
@@ -17110,98 +17110,6 @@ instruct reduce_mul2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp)
ins_pipe(pipe_class_default);
%}

instruct reduce_max2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
match(Set dst (MaxReductionV fsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst, TEMP tmp);
format %{ "fmaxs $dst, $fsrc, $vsrc\n\t"
"ins $tmp, S, $vsrc, 0, 1\n\t"
"fmaxs $dst, $dst, $tmp\t# max reduction2F" %}
ins_encode %{
__ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg));
__ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1);
__ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
%}
ins_pipe(pipe_class_default);
%}

instruct reduce_max4F(vRegF dst, vRegF fsrc, vecX vsrc) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
match(Set dst (MaxReductionV fsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "fmaxv $dst, T4S, $vsrc\n\t"
"fmaxs $dst, $dst, $fsrc\t# max reduction4F" %}
ins_encode %{
__ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg));
__ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg));
%}
ins_pipe(pipe_class_default);
%}

instruct reduce_max2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
match(Set dst (MaxReductionV dsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst, TEMP tmp);
format %{ "fmaxd $dst, $dsrc, $vsrc\n\t"
"ins $tmp, D, $vsrc, 0, 1\n\t"
"fmaxd $dst, $dst, $tmp\t# max reduction2D" %}
ins_encode %{
__ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg));
__ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1);
__ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
%}
ins_pipe(pipe_class_default);
%}

instruct reduce_min2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
match(Set dst (MinReductionV fsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst, TEMP tmp);
format %{ "fmins $dst, $fsrc, $vsrc\n\t"
"ins $tmp, S, $vsrc, 0, 1\n\t"
"fmins $dst, $dst, $tmp\t# min reduction2F" %}
ins_encode %{
__ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg));
__ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1);
__ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
%}
ins_pipe(pipe_class_default);
%}

instruct reduce_min4F(vRegF dst, vRegF fsrc, vecX vsrc) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
match(Set dst (MinReductionV fsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "fminv $dst, T4S, $vsrc\n\t"
"fmins $dst, $dst, $fsrc\t# min reduction4F" %}
ins_encode %{
__ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg));
__ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg));
%}
ins_pipe(pipe_class_default);
%}

instruct reduce_min2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
match(Set dst (MinReductionV dsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst, TEMP tmp);
format %{ "fmind $dst, $dsrc, $vsrc\n\t"
"ins $tmp, D, $vsrc, 0, 1\n\t"
"fmind $dst, $dst, $tmp\t# min reduction2D" %}
ins_encode %{
__ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg));
__ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1);
__ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
%}
ins_pipe(pipe_class_default);
%}

// ====================VECTOR ARITHMETIC=======================================

// --------------------------------- ADD --------------------------------------
@@ -899,6 +899,90 @@ instruct reduce_min2L(iRegLNoSp dst, iRegL isrc, vecX vsrc, iRegLNoSp tmp, rFlag
ins_pipe(pipe_slow);
%}

instruct reduce_max2F(vRegF dst, vRegF fsrc, vecD vsrc) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
match(Set dst (MaxReductionV fsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "fmaxp $dst, $vsrc, S\n\t"
"fmaxs $dst, $dst, $fsrc\t# max reduction2F" %}
ins_encode %{
__ fmaxp(as_FloatRegister($dst$$reg), as_FloatRegister($vsrc$$reg), __ S);
__ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg));
%}
ins_pipe(pipe_class_default);
%}

instruct reduce_max4F(vRegF dst, vRegF fsrc, vecX vsrc) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
match(Set dst (MaxReductionV fsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "fmaxv $dst, T4S, $vsrc\n\t"
"fmaxs $dst, $dst, $fsrc\t# max reduction4F" %}
ins_encode %{
__ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg));
__ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg));
%}
ins_pipe(pipe_class_default);
%}

instruct reduce_max2D(vRegD dst, vRegD dsrc, vecX vsrc) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
match(Set dst (MaxReductionV dsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "fmaxp $dst, $vsrc, D\n\t"
"fmaxd $dst, $dst, $dsrc\t# max reduction2D" %}
ins_encode %{
__ fmaxp(as_FloatRegister($dst$$reg), as_FloatRegister($vsrc$$reg), __ D);
__ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg));
%}
ins_pipe(pipe_class_default);
%}

instruct reduce_min2F(vRegF dst, vRegF fsrc, vecD vsrc) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
match(Set dst (MinReductionV fsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "fminp $dst, $vsrc, S\n\t"
"fmins $dst, $dst, $fsrc\t# min reduction2F" %}
ins_encode %{
__ fminp(as_FloatRegister($dst$$reg), as_FloatRegister($vsrc$$reg), __ S);
__ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg));
%}
ins_pipe(pipe_class_default);
%}

instruct reduce_min4F(vRegF dst, vRegF fsrc, vecX vsrc) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
match(Set dst (MinReductionV fsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "fminv $dst, T4S, $vsrc\n\t"
"fmins $dst, $dst, $fsrc\t# min reduction4F" %}
ins_encode %{
__ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg));
__ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg));
%}
ins_pipe(pipe_class_default);
%}

instruct reduce_min2D(vRegD dst, vRegD dsrc, vecX vsrc) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
match(Set dst (MinReductionV dsrc vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "fminp $dst, $vsrc, D\n\t"
"fmind $dst, $dst, $dsrc\t# min reduction2D" %}
ins_encode %{
__ fminp(as_FloatRegister($dst$$reg), as_FloatRegister($vsrc$$reg), __ D);
__ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg));
%}
ins_pipe(pipe_class_default);
%}

instruct reduce_and8B(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp)
%{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE);
@@ -536,6 +536,30 @@ dnl $1 $2 $3
REDUCE_MAX_MIN_2L(max, Max, GT)
REDUCE_MAX_MIN_2L(min, Min, LT)
dnl
define(`REDUCE_MINMAX_FORD', `
instruct reduce_$1$4$5(vReg$5 dst, vReg$5 $6src, vec$7 vsrc) %{
predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_`'ifelse($5, F, FLOAT, DOUBLE));
match(Set dst (ifelse($1, max, Max, Min)ReductionV $6src vsrc));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "$2 $dst, ifelse($4, 2, $vsrc`, 'ifelse($5, F, S, D), ` T4S, $vsrc')\n\t"
"$3 $dst, $dst, $$6src\t# $1 reduction$4$5" %}
ins_encode %{
__ $2(as_FloatRegister($dst$$reg), ifelse($4, 4, `__ T4S, as_FloatRegister($vsrc$$reg))',
$4$5, 2F, `as_FloatRegister($vsrc$$reg), __ S)',
$4$5, 2D, `as_FloatRegister($vsrc$$reg), __ D)');
__ $3(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($$6src$$reg));
%}
ins_pipe(pipe_class_default);
%}')dnl
dnl $1 $2 $3 $4 $5 $6 $7
REDUCE_MINMAX_FORD(max, fmaxp, fmaxs, 2, F, f, D)
REDUCE_MINMAX_FORD(max, fmaxv, fmaxs, 4, F, f, X)
REDUCE_MINMAX_FORD(max, fmaxp, fmaxd, 2, D, d, X)
REDUCE_MINMAX_FORD(min, fminp, fmins, 2, F, f, D)
REDUCE_MINMAX_FORD(min, fminv, fmins, 4, F, f, X)
REDUCE_MINMAX_FORD(min, fminp, fmind, 2, D, d, X)
dnl
define(`REDUCE_LOGIC_OP_8B', `
instruct reduce_$1`'8B(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp)
%{
@@ -2635,16 +2635,21 @@ void mvnw(Register Rd, Register Rm,
rf(Vn, 5), rf(Vd, 0);
}

// (Floating-point) {a, b} -> (a + b)
void faddp(FloatRegister Vd, FloatRegister Vn, SIMD_RegVariant type) {
assert(type == D || type == S, "Wrong type for faddp");
starti;
f(0b011111100, 31, 23);
f(type == D ? 1 : 0, 22);
f(0b110000110110, 21, 10);
rf(Vn, 5), rf(Vd, 0);
// Floating-point AdvSIMD scalar pairwise
#define INSN(NAME, op1, op2) \
void NAME(FloatRegister Vd, FloatRegister Vn, SIMD_RegVariant type) { \
starti; \
assert(type == D || type == S, "Wrong type for faddp/fmaxp/fminp"); \
f(0b0111111, 31, 25), f(op1, 24, 23), \
f(type == S ? 0 : 1, 22), f(0b11000, 21, 17), f(op2, 16, 10), rf(Vn, 5), rf(Vd, 0); \
}

INSN(faddp, 0b00, 0b0110110);
INSN(fmaxp, 0b00, 0b0111110);
INSN(fminp, 0b01, 0b0111110);

#undef INSN

void ins(FloatRegister Vd, SIMD_RegVariant T, FloatRegister Vn, int didx, int sidx) {
starti;
assert(T != Q, "invalid register variant");
@@ -1401,6 +1401,8 @@ def generate(kind, names):
["sminv", "sminv", "8B"], ["sminv", "sminv", "16B"],
["sminv", "sminv", "4H"], ["sminv", "sminv", "8H"],
["sminv", "sminv", "4S"], ["fminv", "fminv", "4S"],
["fmaxp", "fmaxp", "2S"], ["fmaxp", "fmaxp", "2D"],
["fminp", "fminp", "2S"], ["fminp", "fminp", "2D"],
])

generate(TwoRegNEONOp,

0 comments on commit ccac7aa

Please sign in to comment.