On Thu, 2021-06-17 at 10:19 -0500, Bill Schmidt via Gcc-patches wrote: > 2021-03-05 Bill Schmidt <wschm...@linux.ibm.com> >
Hi, > 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. > --- > 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); Hmm, would it be worthy to rename one of the pair so they both match "_st_" or "_store_" ? CODE_FOR_vsx_store_v1ti CODE_FOR_vsx_st_elemrev_v1ti Same for _ld_ and _load_ , but it's all a conversation for elsewhere... :-) Ok, > + 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; > } ok > 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)) No space after "!" ? (here and later on 'pat'.). > + 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. */ good comment. :-) > + 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)); > + Ok. > > 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); Ok > 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); > + } > + Ok lgtm, thanks -Will > return NULL_RTX; > } >