aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Stubbs <ams@codesourcery.com>2020-06-29 15:20:09 +0100
committerAndrew Stubbs <ams@codesourcery.com>2022-10-11 11:45:38 +0100
commit5cfe08555034b29f301dcfb99a3691c81b2e2def (patch)
treeb9e654f7c58702276a1ba1d159aec08f8726dad0 /gcc
parent0d8753cf30486c4e7fb07455b7cae49aa812c6a4 (diff)
downloadgcc-5cfe08555034b29f301dcfb99a3691c81b2e2def.zip
gcc-5cfe08555034b29f301dcfb99a3691c81b2e2def.tar.gz
gcc-5cfe08555034b29f301dcfb99a3691c81b2e2def.tar.bz2
amdgcn: Add vec_extract for partial vectors
Add vec_extract expanders for all valid pairs of vector types. gcc/ChangeLog: * config/gcn/gcn-protos.h (get_exec): Add prototypes for two variants. * config/gcn/gcn-valu.md (vec_extract<V_ALL:mode><V_ALL_ALT:mode>): New define_expand. * config/gcn/gcn.cc (get_exec): Export the existing function. Add a new overload variant.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/gcn/gcn-protos.h2
-rw-r--r--gcc/config/gcn/gcn-valu.md34
-rw-r--r--gcc/config/gcn/gcn.cc9
3 files changed, 44 insertions, 1 deletions
diff --git a/gcc/config/gcn/gcn-protos.h b/gcc/config/gcn/gcn-protos.h
index 6300c1c..f9a1fc0 100644
--- a/gcc/config/gcn/gcn-protos.h
+++ b/gcc/config/gcn/gcn-protos.h
@@ -24,6 +24,8 @@ extern bool gcn_constant64_p (rtx);
extern bool gcn_constant_p (rtx);
extern rtx gcn_convert_mask_mode (rtx reg);
extern unsigned int gcn_dwarf_register_number (unsigned int regno);
+extern rtx get_exec (int64_t);
+extern rtx get_exec (machine_mode mode);
extern char * gcn_expand_dpp_shr_insn (machine_mode, const char *, int, int);
extern void gcn_expand_epilogue ();
extern rtx gcn_expand_scaled_offsets (addr_space_t as, rtx base, rtx offsets,
diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md
index c7be236..9ea60e1 100644
--- a/gcc/config/gcn/gcn-valu.md
+++ b/gcc/config/gcn/gcn-valu.md
@@ -808,6 +808,40 @@
(set_attr "exec" "none")
(set_attr "laneselect" "yes")])
+(define_expand "vec_extract<V_ALL:mode><V_ALL_ALT:mode>"
+ [(set (match_operand:V_ALL_ALT 0 "register_operand")
+ (vec_select:V_ALL_ALT
+ (match_operand:V_ALL 1 "register_operand")
+ (parallel [(match_operand 2 "immediate_operand")])))]
+ "MODE_VF (<V_ALL_ALT:MODE>mode) < MODE_VF (<V_ALL:MODE>mode)
+ && <V_ALL_ALT:SCALAR_MODE>mode == <V_ALL:SCALAR_MODE>mode"
+ {
+ int numlanes = GET_MODE_NUNITS (<V_ALL_ALT:MODE>mode);
+ int firstlane = INTVAL (operands[2]) * numlanes;
+ rtx tmp;
+
+ if (firstlane == 0)
+ {
+ /* A plain move will do. */
+ tmp = operands[1];
+ } else {
+ /* FIXME: optimize this by using DPP where available. */
+
+ rtx permutation = gen_reg_rtx (<V_ALL:VnSI>mode);
+ emit_insn (gen_vec_series<V_ALL:vnsi> (permutation,
+ GEN_INT (firstlane*4),
+ GEN_INT (4)));
+
+ tmp = gen_reg_rtx (<V_ALL:MODE>mode);
+ emit_insn (gen_ds_bpermute<V_ALL:mode> (tmp, permutation, operands[1],
+ get_exec (<V_ALL:MODE>mode)));
+ }
+
+ emit_move_insn (operands[0],
+ gen_rtx_SUBREG (<V_ALL_ALT:MODE>mode, tmp, 0));
+ DONE;
+ })
+
(define_expand "extract_last_<mode>"
[(match_operand:<SCALAR_MODE> 0 "register_operand")
(match_operand:DI 1 "gcn_alu_operand")
diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
index e1636f6..fdcf290 100644
--- a/gcc/config/gcn/gcn.cc
+++ b/gcc/config/gcn/gcn.cc
@@ -846,7 +846,7 @@ gcn_ira_change_pseudo_allocno_class (int regno, reg_class_t cl,
/* Create a new DImode pseudo reg and emit an instruction to initialize
it to VAL. */
-static rtx
+rtx
get_exec (int64_t val)
{
rtx reg = gen_reg_rtx (DImode);
@@ -854,6 +854,13 @@ get_exec (int64_t val)
return reg;
}
+rtx
+get_exec (machine_mode mode)
+{
+ int vf = (VECTOR_MODE_P (mode) ? GET_MODE_NUNITS (mode) : 1);
+ return get_exec (0xffffffffffffffffUL >> (64-vf));
+}
+
/* }}} */
/* {{{ Immediate constants. */