public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/wschmidt/heads/builtins10)] rs6000: Builtin expansion, part 4
@ 2021-06-15 17:20 William Schmidt
0 siblings, 0 replies; 7+ messages in thread
From: William Schmidt @ 2021-06-15 17:20 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:e5547895f5928f21dcf532cb8d14ce53000cdda8
commit e5547895f5928f21dcf532cb8d14ce53000cdda8
Author: Bill Schmidt <wschmidt@linux.ibm.com>
Date: Fri Mar 5 15:19:57 2021 -0600
rs6000: Builtin expansion, part 4
2021-03-05 Bill Schmidt <wschmidt@linux.ibm.com>
gcc/
* config/rs6000/rs6000-call.c (elemrev_icode): Implement.
(ldv_expand_builtin): Likewise.
(lxvrse_expand_builtin): Likewise.
(lxvrze_expand_builtin): Likewise.
(stv_expand_builtin): Likewise.
Diff:
---
gcc/config/rs6000/rs6000-call.c | 217 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 217 insertions(+)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index b8a9c1bf42a..79cabd6c02b 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14699,12 +14699,114 @@ new_cpu_expand_builtin (enum rs6000_gen_builtins fcode,
static insn_code
elemrev_icode (rs6000_gen_builtins fcode)
{
+ switch (fcode)
+ {
+ default:
+ gcc_unreachable ();
+ case RS6000_BIF_ST_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
+ : CODE_FOR_vsx_st_elemrev_v1ti);
+ case RS6000_BIF_ST_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
+ : CODE_FOR_vsx_st_elemrev_v2df);
+ case RS6000_BIF_ST_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
+ : CODE_FOR_vsx_st_elemrev_v2di);
+ case RS6000_BIF_ST_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
+ : CODE_FOR_vsx_st_elemrev_v4sf);
+ case RS6000_BIF_ST_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
+ : CODE_FOR_vsx_st_elemrev_v4si);
+ case RS6000_BIF_ST_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
+ : CODE_FOR_vsx_st_elemrev_v8hi);
+ case RS6000_BIF_ST_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
+ : CODE_FOR_vsx_st_elemrev_v16qi);
+ case RS6000_BIF_LD_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
+ : CODE_FOR_vsx_ld_elemrev_v2df);
+ case RS6000_BIF_LD_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
+ : CODE_FOR_vsx_ld_elemrev_v1ti);
+ case RS6000_BIF_LD_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
+ : CODE_FOR_vsx_ld_elemrev_v2di);
+ case RS6000_BIF_LD_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
+ : CODE_FOR_vsx_ld_elemrev_v4sf);
+ case RS6000_BIF_LD_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
+ : CODE_FOR_vsx_ld_elemrev_v4si);
+ case RS6000_BIF_LD_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
+ : CODE_FOR_vsx_ld_elemrev_v8hi);
+ case RS6000_BIF_LD_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
+ : CODE_FOR_vsx_ld_elemrev_v16qi);
+ }
+ gcc_unreachable ();
return (insn_code) 0;
}
static rtx
ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode)
{
+ rtx pat, addr;
+ bool blk = (icode == CODE_FOR_altivec_lvlx
+ || icode == CODE_FOR_altivec_lvlxl
+ || icode == CODE_FOR_altivec_lvrx
+ || icode == CODE_FOR_altivec_lvrxl);
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ /* For LVX, express the RTL accurately by ANDing the address with -16.
+ LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_lvx_v1ti
+ || icode == CODE_FOR_altivec_lvx_v2df
+ || icode == CODE_FOR_altivec_lvx_v2di
+ || icode == CODE_FOR_altivec_lvx_v4sf
+ || icode == CODE_FOR_altivec_lvx_v4si
+ || icode == CODE_FOR_altivec_lvx_v8hi
+ || icode == CODE_FOR_altivec_lvx_v16qi)
+ {
+ rtx rawaddr;
+ if (op[0] == const0_rtx)
+ rawaddr = op[1];
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[1], op[0]);
+ }
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
+
+ emit_insn (gen_rtx_SET (target, addr));
+ }
+ else
+ {
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ }
+
return target;
}
@@ -14712,6 +14814,42 @@ static rtx
lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ rtx discratch = gen_reg_rtx (DImode);
+ rtx tiscratch = gen_reg_rtx (TImode);
+
+ /* Emit the lxvr*x insn. */
+ pat = GEN_FCN (icode) (tiscratch, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
+
+ /* Emit a sign extension from QI,HI,WI to double (DI). */
+ rtx scratch = gen_lowpart (smode, tiscratch);
+ if (icode == CODE_FOR_vsx_lxvrbx)
+ emit_insn (gen_extendqidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrhx)
+ emit_insn (gen_extendhidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrwx)
+ emit_insn (gen_extendsidi2 (discratch, scratch));
+ /* Assign discratch directly if scratch is already DI. */
+ if (icode == CODE_FOR_vsx_lxvrdx)
+ discratch = scratch;
+
+ /* Emit the sign extension from DI (double) to TI (quad). */
+ emit_insn (gen_extendditi2 (target, discratch));
+
return target;
}
@@ -14719,6 +14857,22 @@ static rtx
lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
return target;
}
@@ -14726,6 +14880,69 @@ static rtx
stv_expand_builtin (insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr, rawaddr, truncrtx;
+ op[2] = copy_to_mode_reg (Pmode, op[2]);
+
+ /* For STVX, express the RTL accurately by ANDing the address with -16.
+ STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_stvx_v2df
+ || icode == CODE_FOR_altivec_stvx_v2di
+ || icode == CODE_FOR_altivec_stvx_v4sf
+ || icode == CODE_FOR_altivec_stvx_v4si
+ || icode == CODE_FOR_altivec_stvx_v8hi
+ || icode == CODE_FOR_altivec_stvx_v16qi)
+ {
+ if (op[1] == const0_rtx)
+ rawaddr = op[2];
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[2], op[1]);
+ }
+
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (tmode, addr);
+ op[0] = copy_to_mode_reg (tmode, op[0]);
+ emit_insn (gen_rtx_SET (addr, op[0]));
+ }
+ else if (icode == CODE_FOR_vsx_stxvrbx
+ || icode == CODE_FOR_vsx_stxvrhx
+ || icode == CODE_FOR_vsx_stxvrwx
+ || icode == CODE_FOR_vsx_stxvrdx)
+ {
+ truncrtx = gen_rtx_TRUNCATE (tmode, op[0]);
+ op[0] = copy_to_mode_reg (E_TImode, truncrtx);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (Pmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+ else
+ {
+ if (! (*insn_data[icode].operand[1].predicate) (op[0], smode))
+ op[0] = copy_to_mode_reg (smode, op[0]);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+
return NULL_RTX;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* [gcc(refs/users/wschmidt/heads/builtins10)] rs6000: Builtin expansion, part 4
@ 2021-07-29 14:46 William Schmidt
0 siblings, 0 replies; 7+ messages in thread
From: William Schmidt @ 2021-07-29 14:46 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:078e293801b870304865bf951287a2b068841960
commit 078e293801b870304865bf951287a2b068841960
Author: Bill Schmidt <wschmidt@linux.ibm.com>
Date: Wed Jul 28 16:34:22 2021 -0400
rs6000: Builtin expansion, part 4
2021-07-28 Bill Schmidt <wschmidt@linux.ibm.com>
gcc/
* config/rs6000/rs6000-call.c (elemrev_icode): Implement.
(ldv_expand_builtin): Likewise.
(lxvrse_expand_builtin): Likewise.
(lxvrze_expand_builtin): Likewise.
(stv_expand_builtin): Likewise.
Diff:
---
gcc/config/rs6000/rs6000-call.c | 217 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 217 insertions(+)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 4f5aed137fb..89984d65a46 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14772,12 +14772,114 @@ new_cpu_expand_builtin (enum rs6000_gen_builtins fcode,
static insn_code
elemrev_icode (rs6000_gen_builtins fcode)
{
+ switch (fcode)
+ {
+ default:
+ gcc_unreachable ();
+ case RS6000_BIF_ST_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
+ : CODE_FOR_vsx_st_elemrev_v1ti);
+ case RS6000_BIF_ST_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
+ : CODE_FOR_vsx_st_elemrev_v2df);
+ case RS6000_BIF_ST_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
+ : CODE_FOR_vsx_st_elemrev_v2di);
+ case RS6000_BIF_ST_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
+ : CODE_FOR_vsx_st_elemrev_v4sf);
+ case RS6000_BIF_ST_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
+ : CODE_FOR_vsx_st_elemrev_v4si);
+ case RS6000_BIF_ST_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
+ : CODE_FOR_vsx_st_elemrev_v8hi);
+ case RS6000_BIF_ST_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
+ : CODE_FOR_vsx_st_elemrev_v16qi);
+ case RS6000_BIF_LD_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
+ : CODE_FOR_vsx_ld_elemrev_v2df);
+ case RS6000_BIF_LD_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
+ : CODE_FOR_vsx_ld_elemrev_v1ti);
+ case RS6000_BIF_LD_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
+ : CODE_FOR_vsx_ld_elemrev_v2di);
+ case RS6000_BIF_LD_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
+ : CODE_FOR_vsx_ld_elemrev_v4sf);
+ case RS6000_BIF_LD_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
+ : CODE_FOR_vsx_ld_elemrev_v4si);
+ case RS6000_BIF_LD_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
+ : CODE_FOR_vsx_ld_elemrev_v8hi);
+ case RS6000_BIF_LD_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
+ : CODE_FOR_vsx_ld_elemrev_v16qi);
+ }
+ gcc_unreachable ();
return (insn_code) 0;
}
static rtx
ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode)
{
+ rtx pat, addr;
+ bool blk = (icode == CODE_FOR_altivec_lvlx
+ || icode == CODE_FOR_altivec_lvlxl
+ || icode == CODE_FOR_altivec_lvrx
+ || icode == CODE_FOR_altivec_lvrxl);
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || !(*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ /* For LVX, express the RTL accurately by ANDing the address with -16.
+ LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_lvx_v1ti
+ || icode == CODE_FOR_altivec_lvx_v2df
+ || icode == CODE_FOR_altivec_lvx_v2di
+ || icode == CODE_FOR_altivec_lvx_v4sf
+ || icode == CODE_FOR_altivec_lvx_v4si
+ || icode == CODE_FOR_altivec_lvx_v8hi
+ || icode == CODE_FOR_altivec_lvx_v16qi)
+ {
+ rtx rawaddr;
+ if (op[0] == const0_rtx)
+ rawaddr = op[1];
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[1], op[0]);
+ }
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
+
+ emit_insn (gen_rtx_SET (target, addr));
+ }
+ else
+ {
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
+ }
+
return target;
}
@@ -14785,6 +14887,42 @@ static rtx
lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ rtx discratch = gen_reg_rtx (DImode);
+ rtx tiscratch = gen_reg_rtx (TImode);
+
+ /* Emit the lxvr*x insn. */
+ pat = GEN_FCN (icode) (tiscratch, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
+
+ /* Emit a sign extension from QI,HI,WI to double (DI). */
+ rtx scratch = gen_lowpart (smode, tiscratch);
+ if (icode == CODE_FOR_vsx_lxvrbx)
+ emit_insn (gen_extendqidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrhx)
+ emit_insn (gen_extendhidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrwx)
+ emit_insn (gen_extendsidi2 (discratch, scratch));
+ /* Assign discratch directly if scratch is already DI. */
+ if (icode == CODE_FOR_vsx_lxvrdx)
+ discratch = scratch;
+
+ /* Emit the sign extension from DI (double) to TI (quad). */
+ emit_insn (gen_extendditi2 (target, discratch));
+
return target;
}
@@ -14792,6 +14930,22 @@ static rtx
lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
return target;
}
@@ -14799,6 +14953,69 @@ static rtx
stv_expand_builtin (insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr, rawaddr, truncrtx;
+ op[2] = copy_to_mode_reg (Pmode, op[2]);
+
+ /* For STVX, express the RTL accurately by ANDing the address with -16.
+ STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_stvx_v2df
+ || icode == CODE_FOR_altivec_stvx_v2di
+ || icode == CODE_FOR_altivec_stvx_v4sf
+ || icode == CODE_FOR_altivec_stvx_v4si
+ || icode == CODE_FOR_altivec_stvx_v8hi
+ || icode == CODE_FOR_altivec_stvx_v16qi)
+ {
+ if (op[1] == const0_rtx)
+ rawaddr = op[2];
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[2], op[1]);
+ }
+
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (tmode, addr);
+ op[0] = copy_to_mode_reg (tmode, op[0]);
+ emit_insn (gen_rtx_SET (addr, op[0]));
+ }
+ else if (icode == CODE_FOR_vsx_stxvrbx
+ || icode == CODE_FOR_vsx_stxvrhx
+ || icode == CODE_FOR_vsx_stxvrwx
+ || icode == CODE_FOR_vsx_stxvrdx)
+ {
+ truncrtx = gen_rtx_TRUNCATE (tmode, op[0]);
+ op[0] = copy_to_mode_reg (E_TImode, truncrtx);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (Pmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+ else
+ {
+ if (! (*insn_data[icode].operand[1].predicate) (op[0], smode))
+ op[0] = copy_to_mode_reg (smode, op[0]);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+
return NULL_RTX;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* [gcc(refs/users/wschmidt/heads/builtins10)] rs6000: Builtin expansion, part 4
@ 2021-06-25 16:18 William Schmidt
0 siblings, 0 replies; 7+ messages in thread
From: William Schmidt @ 2021-06-25 16:18 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:1f28ba77c244256484e000eab60d041181612ff4
commit 1f28ba77c244256484e000eab60d041181612ff4
Author: Bill Schmidt <wschmidt@linux.ibm.com>
Date: Fri Mar 5 15:19:57 2021 -0600
rs6000: Builtin expansion, part 4
2021-03-05 Bill Schmidt <wschmidt@linux.ibm.com>
gcc/
* config/rs6000/rs6000-call.c (elemrev_icode): Implement.
(ldv_expand_builtin): Likewise.
(lxvrse_expand_builtin): Likewise.
(lxvrze_expand_builtin): Likewise.
(stv_expand_builtin): Likewise.
Diff:
---
gcc/config/rs6000/rs6000-call.c | 217 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 217 insertions(+)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index ad3e6a4bbe5..981eabc1187 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14710,12 +14710,114 @@ new_cpu_expand_builtin (enum rs6000_gen_builtins fcode,
static insn_code
elemrev_icode (rs6000_gen_builtins fcode)
{
+ switch (fcode)
+ {
+ default:
+ gcc_unreachable ();
+ case RS6000_BIF_ST_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
+ : CODE_FOR_vsx_st_elemrev_v1ti);
+ case RS6000_BIF_ST_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
+ : CODE_FOR_vsx_st_elemrev_v2df);
+ case RS6000_BIF_ST_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
+ : CODE_FOR_vsx_st_elemrev_v2di);
+ case RS6000_BIF_ST_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
+ : CODE_FOR_vsx_st_elemrev_v4sf);
+ case RS6000_BIF_ST_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
+ : CODE_FOR_vsx_st_elemrev_v4si);
+ case RS6000_BIF_ST_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
+ : CODE_FOR_vsx_st_elemrev_v8hi);
+ case RS6000_BIF_ST_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
+ : CODE_FOR_vsx_st_elemrev_v16qi);
+ case RS6000_BIF_LD_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
+ : CODE_FOR_vsx_ld_elemrev_v2df);
+ case RS6000_BIF_LD_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
+ : CODE_FOR_vsx_ld_elemrev_v1ti);
+ case RS6000_BIF_LD_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
+ : CODE_FOR_vsx_ld_elemrev_v2di);
+ case RS6000_BIF_LD_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
+ : CODE_FOR_vsx_ld_elemrev_v4sf);
+ case RS6000_BIF_LD_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
+ : CODE_FOR_vsx_ld_elemrev_v4si);
+ case RS6000_BIF_LD_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
+ : CODE_FOR_vsx_ld_elemrev_v8hi);
+ case RS6000_BIF_LD_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
+ : CODE_FOR_vsx_ld_elemrev_v16qi);
+ }
+ gcc_unreachable ();
return (insn_code) 0;
}
static rtx
ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode)
{
+ rtx pat, addr;
+ bool blk = (icode == CODE_FOR_altivec_lvlx
+ || icode == CODE_FOR_altivec_lvlxl
+ || icode == CODE_FOR_altivec_lvrx
+ || icode == CODE_FOR_altivec_lvrxl);
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ /* For LVX, express the RTL accurately by ANDing the address with -16.
+ LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_lvx_v1ti
+ || icode == CODE_FOR_altivec_lvx_v2df
+ || icode == CODE_FOR_altivec_lvx_v2di
+ || icode == CODE_FOR_altivec_lvx_v4sf
+ || icode == CODE_FOR_altivec_lvx_v4si
+ || icode == CODE_FOR_altivec_lvx_v8hi
+ || icode == CODE_FOR_altivec_lvx_v16qi)
+ {
+ rtx rawaddr;
+ if (op[0] == const0_rtx)
+ rawaddr = op[1];
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[1], op[0]);
+ }
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
+
+ emit_insn (gen_rtx_SET (target, addr));
+ }
+ else
+ {
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ }
+
return target;
}
@@ -14723,6 +14825,42 @@ static rtx
lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ rtx discratch = gen_reg_rtx (DImode);
+ rtx tiscratch = gen_reg_rtx (TImode);
+
+ /* Emit the lxvr*x insn. */
+ pat = GEN_FCN (icode) (tiscratch, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
+
+ /* Emit a sign extension from QI,HI,WI to double (DI). */
+ rtx scratch = gen_lowpart (smode, tiscratch);
+ if (icode == CODE_FOR_vsx_lxvrbx)
+ emit_insn (gen_extendqidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrhx)
+ emit_insn (gen_extendhidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrwx)
+ emit_insn (gen_extendsidi2 (discratch, scratch));
+ /* Assign discratch directly if scratch is already DI. */
+ if (icode == CODE_FOR_vsx_lxvrdx)
+ discratch = scratch;
+
+ /* Emit the sign extension from DI (double) to TI (quad). */
+ emit_insn (gen_extendditi2 (target, discratch));
+
return target;
}
@@ -14730,6 +14868,22 @@ static rtx
lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
return target;
}
@@ -14737,6 +14891,69 @@ static rtx
stv_expand_builtin (insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr, rawaddr, truncrtx;
+ op[2] = copy_to_mode_reg (Pmode, op[2]);
+
+ /* For STVX, express the RTL accurately by ANDing the address with -16.
+ STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_stvx_v2df
+ || icode == CODE_FOR_altivec_stvx_v2di
+ || icode == CODE_FOR_altivec_stvx_v4sf
+ || icode == CODE_FOR_altivec_stvx_v4si
+ || icode == CODE_FOR_altivec_stvx_v8hi
+ || icode == CODE_FOR_altivec_stvx_v16qi)
+ {
+ if (op[1] == const0_rtx)
+ rawaddr = op[2];
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[2], op[1]);
+ }
+
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (tmode, addr);
+ op[0] = copy_to_mode_reg (tmode, op[0]);
+ emit_insn (gen_rtx_SET (addr, op[0]));
+ }
+ else if (icode == CODE_FOR_vsx_stxvrbx
+ || icode == CODE_FOR_vsx_stxvrhx
+ || icode == CODE_FOR_vsx_stxvrwx
+ || icode == CODE_FOR_vsx_stxvrdx)
+ {
+ truncrtx = gen_rtx_TRUNCATE (tmode, op[0]);
+ op[0] = copy_to_mode_reg (E_TImode, truncrtx);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (Pmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+ else
+ {
+ if (! (*insn_data[icode].operand[1].predicate) (op[0], smode))
+ op[0] = copy_to_mode_reg (smode, op[0]);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+
return NULL_RTX;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* [gcc(refs/users/wschmidt/heads/builtins10)] rs6000: Builtin expansion, part 4
@ 2021-04-26 20:52 William Schmidt
0 siblings, 0 replies; 7+ messages in thread
From: William Schmidt @ 2021-04-26 20:52 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:3ba8a09295925d0530ce0657c49d32560c8ac750
commit 3ba8a09295925d0530ce0657c49d32560c8ac750
Author: Bill Schmidt <wschmidt@linux.ibm.com>
Date: Fri Mar 5 15:19:57 2021 -0600
rs6000: Builtin expansion, part 4
2021-03-05 Bill Schmidt <wschmidt@linux.ibm.com>
gcc/
* config/rs6000/rs6000-call.c (elemrev_icode): Implement.
(ldv_expand_builtin): Likewise.
(lxvrse_expand_builtin): Likewise.
(lxvrze_expand_builtin): Likewise.
(stv_expand_builtin): Likewise.
Diff:
---
gcc/config/rs6000/rs6000-call.c | 217 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 217 insertions(+)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index a568682592c..2d8a784a3c8 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14586,12 +14586,114 @@ new_cpu_expand_builtin (enum rs6000_gen_builtins fcode,
static insn_code
elemrev_icode (rs6000_gen_builtins fcode)
{
+ switch (fcode)
+ {
+ default:
+ gcc_unreachable ();
+ case RS6000_BIF_ST_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
+ : CODE_FOR_vsx_st_elemrev_v1ti);
+ case RS6000_BIF_ST_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
+ : CODE_FOR_vsx_st_elemrev_v2df);
+ case RS6000_BIF_ST_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
+ : CODE_FOR_vsx_st_elemrev_v2di);
+ case RS6000_BIF_ST_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
+ : CODE_FOR_vsx_st_elemrev_v4sf);
+ case RS6000_BIF_ST_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
+ : CODE_FOR_vsx_st_elemrev_v4si);
+ case RS6000_BIF_ST_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
+ : CODE_FOR_vsx_st_elemrev_v8hi);
+ case RS6000_BIF_ST_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
+ : CODE_FOR_vsx_st_elemrev_v16qi);
+ case RS6000_BIF_LD_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
+ : CODE_FOR_vsx_ld_elemrev_v2df);
+ case RS6000_BIF_LD_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
+ : CODE_FOR_vsx_ld_elemrev_v1ti);
+ case RS6000_BIF_LD_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
+ : CODE_FOR_vsx_ld_elemrev_v2di);
+ case RS6000_BIF_LD_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
+ : CODE_FOR_vsx_ld_elemrev_v4sf);
+ case RS6000_BIF_LD_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
+ : CODE_FOR_vsx_ld_elemrev_v4si);
+ case RS6000_BIF_LD_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
+ : CODE_FOR_vsx_ld_elemrev_v8hi);
+ case RS6000_BIF_LD_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
+ : CODE_FOR_vsx_ld_elemrev_v16qi);
+ }
+ gcc_unreachable ();
return (insn_code) 0;
}
static rtx
ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode)
{
+ rtx pat, addr;
+ bool blk = (icode == CODE_FOR_altivec_lvlx
+ || icode == CODE_FOR_altivec_lvlxl
+ || icode == CODE_FOR_altivec_lvrx
+ || icode == CODE_FOR_altivec_lvrxl);
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ /* For LVX, express the RTL accurately by ANDing the address with -16.
+ LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_lvx_v1ti
+ || icode == CODE_FOR_altivec_lvx_v2df
+ || icode == CODE_FOR_altivec_lvx_v2di
+ || icode == CODE_FOR_altivec_lvx_v4sf
+ || icode == CODE_FOR_altivec_lvx_v4si
+ || icode == CODE_FOR_altivec_lvx_v8hi
+ || icode == CODE_FOR_altivec_lvx_v16qi)
+ {
+ rtx rawaddr;
+ if (op[0] == const0_rtx)
+ rawaddr = op[1];
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[1], op[0]);
+ }
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
+
+ emit_insn (gen_rtx_SET (target, addr));
+ }
+ else
+ {
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ }
+
return target;
}
@@ -14599,6 +14701,42 @@ static rtx
lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ rtx discratch = gen_reg_rtx (DImode);
+ rtx tiscratch = gen_reg_rtx (TImode);
+
+ /* Emit the lxvr*x insn. */
+ pat = GEN_FCN (icode) (tiscratch, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
+
+ /* Emit a sign extension from QI,HI,WI to double (DI). */
+ rtx scratch = gen_lowpart (smode, tiscratch);
+ if (icode == CODE_FOR_vsx_lxvrbx)
+ emit_insn (gen_extendqidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrhx)
+ emit_insn (gen_extendhidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrwx)
+ emit_insn (gen_extendsidi2 (discratch, scratch));
+ /* Assign discratch directly if scratch is already DI. */
+ if (icode == CODE_FOR_vsx_lxvrdx)
+ discratch = scratch;
+
+ /* Emit the sign extension from DI (double) to TI (quad). */
+ emit_insn (gen_extendditi2 (target, discratch));
+
return target;
}
@@ -14606,6 +14744,22 @@ static rtx
lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
return target;
}
@@ -14613,6 +14767,69 @@ static rtx
stv_expand_builtin (insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr, rawaddr, truncrtx;
+ op[2] = copy_to_mode_reg (Pmode, op[2]);
+
+ /* For STVX, express the RTL accurately by ANDing the address with -16.
+ STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_stvx_v2df
+ || icode == CODE_FOR_altivec_stvx_v2di
+ || icode == CODE_FOR_altivec_stvx_v4sf
+ || icode == CODE_FOR_altivec_stvx_v4si
+ || icode == CODE_FOR_altivec_stvx_v8hi
+ || icode == CODE_FOR_altivec_stvx_v16qi)
+ {
+ if (op[1] == const0_rtx)
+ rawaddr = op[2];
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[2], op[1]);
+ }
+
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (tmode, addr);
+ op[0] = copy_to_mode_reg (tmode, op[0]);
+ emit_insn (gen_rtx_SET (addr, op[0]));
+ }
+ else if (icode == CODE_FOR_vsx_stxvrbx
+ || icode == CODE_FOR_vsx_stxvrhx
+ || icode == CODE_FOR_vsx_stxvrwx
+ || icode == CODE_FOR_vsx_stxvrdx)
+ {
+ truncrtx = gen_rtx_TRUNCATE (tmode, op[0]);
+ op[0] = copy_to_mode_reg (E_TImode, truncrtx);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (Pmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+ else
+ {
+ if (! (*insn_data[icode].operand[1].predicate) (op[0], smode))
+ op[0] = copy_to_mode_reg (smode, op[0]);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+
return NULL_RTX;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* [gcc(refs/users/wschmidt/heads/builtins10)] rs6000: Builtin expansion, part 4
@ 2021-04-02 22:12 William Schmidt
0 siblings, 0 replies; 7+ messages in thread
From: William Schmidt @ 2021-04-02 22:12 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:2ef7b2b101fb816b0e06e5e65d3fb51741cc457b
commit 2ef7b2b101fb816b0e06e5e65d3fb51741cc457b
Author: Bill Schmidt <wschmidt@linux.ibm.com>
Date: Fri Mar 5 15:19:57 2021 -0600
rs6000: Builtin expansion, part 4
2021-03-05 Bill Schmidt <wschmidt@linux.ibm.com>
gcc/
* config/rs6000/rs6000-call.c (elemrev_icode): Implement.
(ldv_expand_builtin): Likewise.
(lxvrse_expand_builtin): Likewise.
(lxvrze_expand_builtin): Likewise.
(stv_expand_builtin): Likewise.
Diff:
---
gcc/config/rs6000/rs6000-call.c | 217 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 217 insertions(+)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index a568682592c..2d8a784a3c8 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14586,12 +14586,114 @@ new_cpu_expand_builtin (enum rs6000_gen_builtins fcode,
static insn_code
elemrev_icode (rs6000_gen_builtins fcode)
{
+ switch (fcode)
+ {
+ default:
+ gcc_unreachable ();
+ case RS6000_BIF_ST_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
+ : CODE_FOR_vsx_st_elemrev_v1ti);
+ case RS6000_BIF_ST_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
+ : CODE_FOR_vsx_st_elemrev_v2df);
+ case RS6000_BIF_ST_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
+ : CODE_FOR_vsx_st_elemrev_v2di);
+ case RS6000_BIF_ST_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
+ : CODE_FOR_vsx_st_elemrev_v4sf);
+ case RS6000_BIF_ST_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
+ : CODE_FOR_vsx_st_elemrev_v4si);
+ case RS6000_BIF_ST_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
+ : CODE_FOR_vsx_st_elemrev_v8hi);
+ case RS6000_BIF_ST_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
+ : CODE_FOR_vsx_st_elemrev_v16qi);
+ case RS6000_BIF_LD_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
+ : CODE_FOR_vsx_ld_elemrev_v2df);
+ case RS6000_BIF_LD_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
+ : CODE_FOR_vsx_ld_elemrev_v1ti);
+ case RS6000_BIF_LD_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
+ : CODE_FOR_vsx_ld_elemrev_v2di);
+ case RS6000_BIF_LD_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
+ : CODE_FOR_vsx_ld_elemrev_v4sf);
+ case RS6000_BIF_LD_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
+ : CODE_FOR_vsx_ld_elemrev_v4si);
+ case RS6000_BIF_LD_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
+ : CODE_FOR_vsx_ld_elemrev_v8hi);
+ case RS6000_BIF_LD_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
+ : CODE_FOR_vsx_ld_elemrev_v16qi);
+ }
+ gcc_unreachable ();
return (insn_code) 0;
}
static rtx
ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode)
{
+ rtx pat, addr;
+ bool blk = (icode == CODE_FOR_altivec_lvlx
+ || icode == CODE_FOR_altivec_lvlxl
+ || icode == CODE_FOR_altivec_lvrx
+ || icode == CODE_FOR_altivec_lvrxl);
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ /* For LVX, express the RTL accurately by ANDing the address with -16.
+ LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_lvx_v1ti
+ || icode == CODE_FOR_altivec_lvx_v2df
+ || icode == CODE_FOR_altivec_lvx_v2di
+ || icode == CODE_FOR_altivec_lvx_v4sf
+ || icode == CODE_FOR_altivec_lvx_v4si
+ || icode == CODE_FOR_altivec_lvx_v8hi
+ || icode == CODE_FOR_altivec_lvx_v16qi)
+ {
+ rtx rawaddr;
+ if (op[0] == const0_rtx)
+ rawaddr = op[1];
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[1], op[0]);
+ }
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
+
+ emit_insn (gen_rtx_SET (target, addr));
+ }
+ else
+ {
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ }
+
return target;
}
@@ -14599,6 +14701,42 @@ static rtx
lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ rtx discratch = gen_reg_rtx (DImode);
+ rtx tiscratch = gen_reg_rtx (TImode);
+
+ /* Emit the lxvr*x insn. */
+ pat = GEN_FCN (icode) (tiscratch, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
+
+ /* Emit a sign extension from QI,HI,WI to double (DI). */
+ rtx scratch = gen_lowpart (smode, tiscratch);
+ if (icode == CODE_FOR_vsx_lxvrbx)
+ emit_insn (gen_extendqidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrhx)
+ emit_insn (gen_extendhidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrwx)
+ emit_insn (gen_extendsidi2 (discratch, scratch));
+ /* Assign discratch directly if scratch is already DI. */
+ if (icode == CODE_FOR_vsx_lxvrdx)
+ discratch = scratch;
+
+ /* Emit the sign extension from DI (double) to TI (quad). */
+ emit_insn (gen_extendditi2 (target, discratch));
+
return target;
}
@@ -14606,6 +14744,22 @@ static rtx
lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
return target;
}
@@ -14613,6 +14767,69 @@ static rtx
stv_expand_builtin (insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr, rawaddr, truncrtx;
+ op[2] = copy_to_mode_reg (Pmode, op[2]);
+
+ /* For STVX, express the RTL accurately by ANDing the address with -16.
+ STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_stvx_v2df
+ || icode == CODE_FOR_altivec_stvx_v2di
+ || icode == CODE_FOR_altivec_stvx_v4sf
+ || icode == CODE_FOR_altivec_stvx_v4si
+ || icode == CODE_FOR_altivec_stvx_v8hi
+ || icode == CODE_FOR_altivec_stvx_v16qi)
+ {
+ if (op[1] == const0_rtx)
+ rawaddr = op[2];
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[2], op[1]);
+ }
+
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (tmode, addr);
+ op[0] = copy_to_mode_reg (tmode, op[0]);
+ emit_insn (gen_rtx_SET (addr, op[0]));
+ }
+ else if (icode == CODE_FOR_vsx_stxvrbx
+ || icode == CODE_FOR_vsx_stxvrhx
+ || icode == CODE_FOR_vsx_stxvrwx
+ || icode == CODE_FOR_vsx_stxvrdx)
+ {
+ truncrtx = gen_rtx_TRUNCATE (tmode, op[0]);
+ op[0] = copy_to_mode_reg (E_TImode, truncrtx);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (Pmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+ else
+ {
+ if (! (*insn_data[icode].operand[1].predicate) (op[0], smode))
+ op[0] = copy_to_mode_reg (smode, op[0]);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+
return NULL_RTX;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* [gcc(refs/users/wschmidt/heads/builtins10)] rs6000: Builtin expansion, part 4
@ 2021-04-01 19:50 William Schmidt
0 siblings, 0 replies; 7+ messages in thread
From: William Schmidt @ 2021-04-01 19:50 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:ebea7f0126fc20debe1a4889effbcbb3ad7bac09
commit ebea7f0126fc20debe1a4889effbcbb3ad7bac09
Author: Bill Schmidt <wschmidt@linux.ibm.com>
Date: Fri Mar 5 15:19:57 2021 -0600
rs6000: Builtin expansion, part 4
2021-03-05 Bill Schmidt <wschmidt@linux.ibm.com>
gcc/
* config/rs6000/rs6000-call.c (elemrev_icode): Implement.
(ldv_expand_builtin): Likewise.
(lxvrse_expand_builtin): Likewise.
(lxvrze_expand_builtin): Likewise.
(stv_expand_builtin): Likewise.
Diff:
---
gcc/config/rs6000/rs6000-call.c | 217 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 217 insertions(+)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index b7ee6d2759e..f64a6854373 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14586,12 +14586,114 @@ new_cpu_expand_builtin (enum rs6000_gen_builtins fcode,
static insn_code
elemrev_icode (rs6000_gen_builtins fcode)
{
+ switch (fcode)
+ {
+ default:
+ gcc_unreachable ();
+ case RS6000_BIF_ST_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
+ : CODE_FOR_vsx_st_elemrev_v1ti);
+ case RS6000_BIF_ST_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
+ : CODE_FOR_vsx_st_elemrev_v2df);
+ case RS6000_BIF_ST_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
+ : CODE_FOR_vsx_st_elemrev_v2di);
+ case RS6000_BIF_ST_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
+ : CODE_FOR_vsx_st_elemrev_v4sf);
+ case RS6000_BIF_ST_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
+ : CODE_FOR_vsx_st_elemrev_v4si);
+ case RS6000_BIF_ST_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
+ : CODE_FOR_vsx_st_elemrev_v8hi);
+ case RS6000_BIF_ST_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
+ : CODE_FOR_vsx_st_elemrev_v16qi);
+ case RS6000_BIF_LD_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
+ : CODE_FOR_vsx_ld_elemrev_v2df);
+ case RS6000_BIF_LD_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
+ : CODE_FOR_vsx_ld_elemrev_v1ti);
+ case RS6000_BIF_LD_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
+ : CODE_FOR_vsx_ld_elemrev_v2di);
+ case RS6000_BIF_LD_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
+ : CODE_FOR_vsx_ld_elemrev_v4sf);
+ case RS6000_BIF_LD_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
+ : CODE_FOR_vsx_ld_elemrev_v4si);
+ case RS6000_BIF_LD_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
+ : CODE_FOR_vsx_ld_elemrev_v8hi);
+ case RS6000_BIF_LD_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
+ : CODE_FOR_vsx_ld_elemrev_v16qi);
+ }
+ gcc_unreachable ();
return (insn_code) 0;
}
static rtx
ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode)
{
+ rtx pat, addr;
+ bool blk = (icode == CODE_FOR_altivec_lvlx
+ || icode == CODE_FOR_altivec_lvlxl
+ || icode == CODE_FOR_altivec_lvrx
+ || icode == CODE_FOR_altivec_lvrxl);
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ /* For LVX, express the RTL accurately by ANDing the address with -16.
+ LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_lvx_v1ti
+ || icode == CODE_FOR_altivec_lvx_v2df
+ || icode == CODE_FOR_altivec_lvx_v2di
+ || icode == CODE_FOR_altivec_lvx_v4sf
+ || icode == CODE_FOR_altivec_lvx_v4si
+ || icode == CODE_FOR_altivec_lvx_v8hi
+ || icode == CODE_FOR_altivec_lvx_v16qi)
+ {
+ rtx rawaddr;
+ if (op[0] == const0_rtx)
+ rawaddr = op[1];
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[1], op[0]);
+ }
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
+
+ emit_insn (gen_rtx_SET (target, addr));
+ }
+ else
+ {
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ }
+
return target;
}
@@ -14599,6 +14701,42 @@ static rtx
lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ rtx discratch = gen_reg_rtx (DImode);
+ rtx tiscratch = gen_reg_rtx (TImode);
+
+ /* Emit the lxvr*x insn. */
+ pat = GEN_FCN (icode) (tiscratch, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
+
+ /* Emit a sign extension from QI,HI,WI to double (DI). */
+ rtx scratch = gen_lowpart (smode, tiscratch);
+ if (icode == CODE_FOR_vsx_lxvrbx)
+ emit_insn (gen_extendqidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrhx)
+ emit_insn (gen_extendhidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrwx)
+ emit_insn (gen_extendsidi2 (discratch, scratch));
+ /* Assign discratch directly if scratch is already DI. */
+ if (icode == CODE_FOR_vsx_lxvrdx)
+ discratch = scratch;
+
+ /* Emit the sign extension from DI (double) to TI (quad). */
+ emit_insn (gen_extendditi2 (target, discratch));
+
return target;
}
@@ -14606,6 +14744,22 @@ static rtx
lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
return target;
}
@@ -14613,6 +14767,69 @@ static rtx
stv_expand_builtin (insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr, rawaddr, truncrtx;
+ op[2] = copy_to_mode_reg (Pmode, op[2]);
+
+ /* For STVX, express the RTL accurately by ANDing the address with -16.
+ STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_stvx_v2df
+ || icode == CODE_FOR_altivec_stvx_v2di
+ || icode == CODE_FOR_altivec_stvx_v4sf
+ || icode == CODE_FOR_altivec_stvx_v4si
+ || icode == CODE_FOR_altivec_stvx_v8hi
+ || icode == CODE_FOR_altivec_stvx_v16qi)
+ {
+ if (op[1] == const0_rtx)
+ rawaddr = op[2];
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[2], op[1]);
+ }
+
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (tmode, addr);
+ op[0] = copy_to_mode_reg (tmode, op[0]);
+ emit_insn (gen_rtx_SET (addr, op[0]));
+ }
+ else if (icode == CODE_FOR_vsx_stxvrbx
+ || icode == CODE_FOR_vsx_stxvrhx
+ || icode == CODE_FOR_vsx_stxvrwx
+ || icode == CODE_FOR_vsx_stxvrdx)
+ {
+ truncrtx = gen_rtx_TRUNCATE (tmode, op[0]);
+ op[0] = copy_to_mode_reg (E_TImode, truncrtx);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (Pmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+ else
+ {
+ if (! (*insn_data[icode].operand[1].predicate) (op[0], smode))
+ op[0] = copy_to_mode_reg (smode, op[0]);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+
return NULL_RTX;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* [gcc(refs/users/wschmidt/heads/builtins10)] rs6000: Builtin expansion, part 4
@ 2021-03-25 15:48 William Schmidt
0 siblings, 0 replies; 7+ messages in thread
From: William Schmidt @ 2021-03-25 15:48 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:a806f5f58c7cb5dfc6259b56467630cd3c3ee4da
commit a806f5f58c7cb5dfc6259b56467630cd3c3ee4da
Author: Bill Schmidt <wschmidt@linux.ibm.com>
Date: Fri Mar 5 15:19:57 2021 -0600
rs6000: Builtin expansion, part 4
2021-03-05 Bill Schmidt <wschmidt@linux.ibm.com>
gcc/
* config/rs6000/rs6000-call.c (elemrev_icode): Implement.
(ldv_expand_builtin): Likewise.
(lxvrse_expand_builtin): Likewise.
(lxvrze_expand_builtin): Likewise.
(stv_expand_builtin): Likewise.
Diff:
---
gcc/config/rs6000/rs6000-call.c | 217 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 217 insertions(+)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index b7ee6d2759e..f64a6854373 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14586,12 +14586,114 @@ new_cpu_expand_builtin (enum rs6000_gen_builtins fcode,
static insn_code
elemrev_icode (rs6000_gen_builtins fcode)
{
+ switch (fcode)
+ {
+ default:
+ gcc_unreachable ();
+ case RS6000_BIF_ST_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
+ : CODE_FOR_vsx_st_elemrev_v1ti);
+ case RS6000_BIF_ST_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
+ : CODE_FOR_vsx_st_elemrev_v2df);
+ case RS6000_BIF_ST_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
+ : CODE_FOR_vsx_st_elemrev_v2di);
+ case RS6000_BIF_ST_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
+ : CODE_FOR_vsx_st_elemrev_v4sf);
+ case RS6000_BIF_ST_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
+ : CODE_FOR_vsx_st_elemrev_v4si);
+ case RS6000_BIF_ST_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
+ : CODE_FOR_vsx_st_elemrev_v8hi);
+ case RS6000_BIF_ST_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
+ : CODE_FOR_vsx_st_elemrev_v16qi);
+ case RS6000_BIF_LD_ELEMREV_V2DF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
+ : CODE_FOR_vsx_ld_elemrev_v2df);
+ case RS6000_BIF_LD_ELEMREV_V1TI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
+ : CODE_FOR_vsx_ld_elemrev_v1ti);
+ case RS6000_BIF_LD_ELEMREV_V2DI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
+ : CODE_FOR_vsx_ld_elemrev_v2di);
+ case RS6000_BIF_LD_ELEMREV_V4SF:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
+ : CODE_FOR_vsx_ld_elemrev_v4sf);
+ case RS6000_BIF_LD_ELEMREV_V4SI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
+ : CODE_FOR_vsx_ld_elemrev_v4si);
+ case RS6000_BIF_LD_ELEMREV_V8HI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
+ : CODE_FOR_vsx_ld_elemrev_v8hi);
+ case RS6000_BIF_LD_ELEMREV_V16QI:
+ return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
+ : CODE_FOR_vsx_ld_elemrev_v16qi);
+ }
+ gcc_unreachable ();
return (insn_code) 0;
}
static rtx
ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode)
{
+ rtx pat, addr;
+ bool blk = (icode == CODE_FOR_altivec_lvlx
+ || icode == CODE_FOR_altivec_lvlxl
+ || icode == CODE_FOR_altivec_lvrx
+ || icode == CODE_FOR_altivec_lvrxl);
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ /* For LVX, express the RTL accurately by ANDing the address with -16.
+ LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_lvx_v1ti
+ || icode == CODE_FOR_altivec_lvx_v2df
+ || icode == CODE_FOR_altivec_lvx_v2di
+ || icode == CODE_FOR_altivec_lvx_v4sf
+ || icode == CODE_FOR_altivec_lvx_v4si
+ || icode == CODE_FOR_altivec_lvx_v8hi
+ || icode == CODE_FOR_altivec_lvx_v16qi)
+ {
+ rtx rawaddr;
+ if (op[0] == const0_rtx)
+ rawaddr = op[1];
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[1], op[0]);
+ }
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
+
+ emit_insn (gen_rtx_SET (target, addr));
+ }
+ else
+ {
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ }
+
return target;
}
@@ -14599,6 +14701,42 @@ static rtx
lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ rtx discratch = gen_reg_rtx (DImode);
+ rtx tiscratch = gen_reg_rtx (TImode);
+
+ /* Emit the lxvr*x insn. */
+ pat = GEN_FCN (icode) (tiscratch, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
+
+ /* Emit a sign extension from QI,HI,WI to double (DI). */
+ rtx scratch = gen_lowpart (smode, tiscratch);
+ if (icode == CODE_FOR_vsx_lxvrbx)
+ emit_insn (gen_extendqidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrhx)
+ emit_insn (gen_extendhidi2 (discratch, scratch));
+ else if (icode == CODE_FOR_vsx_lxvrwx)
+ emit_insn (gen_extendsidi2 (discratch, scratch));
+ /* Assign discratch directly if scratch is already DI. */
+ if (icode == CODE_FOR_vsx_lxvrdx)
+ discratch = scratch;
+
+ /* Emit the sign extension from DI (double) to TI (quad). */
+ emit_insn (gen_extendditi2 (target, discratch));
+
return target;
}
@@ -14606,6 +14744,22 @@ static rtx
lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr;
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+ if (op[0] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[1]);
+ else
+ {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (smode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
return target;
}
@@ -14613,6 +14767,69 @@ static rtx
stv_expand_builtin (insn_code icode, rtx *op,
machine_mode tmode, machine_mode smode)
{
+ rtx pat, addr, rawaddr, truncrtx;
+ op[2] = copy_to_mode_reg (Pmode, op[2]);
+
+ /* For STVX, express the RTL accurately by ANDing the address with -16.
+ STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_stvx_v2df
+ || icode == CODE_FOR_altivec_stvx_v2di
+ || icode == CODE_FOR_altivec_stvx_v4sf
+ || icode == CODE_FOR_altivec_stvx_v4si
+ || icode == CODE_FOR_altivec_stvx_v8hi
+ || icode == CODE_FOR_altivec_stvx_v16qi)
+ {
+ if (op[1] == const0_rtx)
+ rawaddr = op[2];
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[2], op[1]);
+ }
+
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (tmode, addr);
+ op[0] = copy_to_mode_reg (tmode, op[0]);
+ emit_insn (gen_rtx_SET (addr, op[0]));
+ }
+ else if (icode == CODE_FOR_vsx_stxvrbx
+ || icode == CODE_FOR_vsx_stxvrhx
+ || icode == CODE_FOR_vsx_stxvrwx
+ || icode == CODE_FOR_vsx_stxvrdx)
+ {
+ truncrtx = gen_rtx_TRUNCATE (tmode, op[0]);
+ op[0] = copy_to_mode_reg (E_TImode, truncrtx);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (Pmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+ else
+ {
+ if (! (*insn_data[icode].operand[1].predicate) (op[0], smode))
+ op[0] = copy_to_mode_reg (smode, op[0]);
+
+ if (op[1] == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op[2]);
+ else
+ {
+ op[1] = copy_to_mode_reg (Pmode, op[1]);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+ }
+
+ pat = GEN_FCN (icode) (addr, op[0]);
+ if (pat)
+ emit_insn (pat);
+ }
+
return NULL_RTX;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2021-07-29 14:46 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-15 17:20 [gcc(refs/users/wschmidt/heads/builtins10)] rs6000: Builtin expansion, part 4 William Schmidt
-- strict thread matches above, loose matches on Subject: below --
2021-07-29 14:46 William Schmidt
2021-06-25 16:18 William Schmidt
2021-04-26 20:52 William Schmidt
2021-04-02 22:12 William Schmidt
2021-04-01 19:50 William Schmidt
2021-03-25 15:48 William Schmidt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).