> +
> +(define_memory_constraint "Qmx"
> +  "@internal
> +   An address valid for GPR."
> +  (and (match_code "mem")
> +       (match_test "!riscv_legitimize_address_index_p (
> +                   XEXP (op, 0), GET_MODE (op), false)")))

Check TARGET_XTHEADFMEMIDX, and I don't quite understand why it
comes with `!` for the riscv_legitimize_address_index_p,
but saying it's an address valid for GPR?

According to the comment it sounds like (mem (reg)) but seems like not?


> diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
> index 019a0e08285..ba53bf710d7 100644
> --- a/gcc/config/riscv/riscv-protos.h
> +++ b/gcc/config/riscv/riscv-protos.h
> @@ -77,6 +77,8 @@ extern const char *
>  riscv_output_move_index (rtx x, machine_mode mode, bool ldr);
>  extern const char *
>  riscv_output_move_modify (rtx x, machine_mode mode, bool ldi);
> +extern const char *
> +riscv_output_move_index_float (rtx x, machine_mode mode, bool ldr);
>
>  extern bool
>  riscv_legitimize_address_index_p (rtx x, machine_mode mode, bool uindex);
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 2980dbd69f9..caa30eed8d6 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -1316,7 +1316,7 @@ riscv_classify_address_index (struct riscv_address_info 
> *info, rtx x,
>    rtx index;
>    int shift = 0;
>
> -  if (!TARGET_XTHEADMEMIDX)
> +  if (!(TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX))
>      return false;
>
>    if (!TARGET_64BIT && mode == DImode)
> @@ -1326,6 +1326,8 @@ riscv_classify_address_index (struct riscv_address_info 
> *info, rtx x,
>      {
>        if (!TARGET_HARD_FLOAT)
>         return false;
> +      if (!(TARGET_HARD_FLOAT && TARGET_XTHEADFMEMIDX))
> +       return false;
>        if (GET_MODE_SIZE (mode).to_constant () == 2)
>         return false;
>      }
> @@ -1422,7 +1424,7 @@ riscv_classify_address_modify (struct 
> riscv_address_info *info, rtx x,
>    ? (SHIFT) + 1 \
>    : 0)
>
> -  if (!TARGET_XTHEADMEMIDX)
> +  if (!(TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX))
>      return false;
>
>    if (!(INTEGRAL_MODE_P (mode) && GET_MODE_SIZE (mode).to_constant () <= 8))
> @@ -1562,6 +1564,42 @@ riscv_output_move_index (rtx x, machine_mode mode, 
> bool ldr)
>    return buf;
>  }
>
> +const char *
> +riscv_output_move_index_float (rtx x, machine_mode mode, bool ldr)
> +{
> +  static char buf[128] = {0};
> +
> +  int index = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
> +  if (!IN_RANGE (index, 2, 3))
> +    return NULL;
> +
> +  if (!riscv_legitimize_address_index_p (x, mode, false))
> +    return NULL;
> +
> +  bool uindex = riscv_legitimize_address_index_p (x, mode, true);
> +
> +  /* Not using index, 0, 1, as they are not implemented
> +     for xtheadfmemidx yet.  */
> +  const char *const insn[][4] = {
> +    {
> +      "th.fs%srb\t%%z1,%%0",
> +      "th.fs%srh\t%%z1,%%0",
> +      "th.fs%srw\t%%z1,%%0",
> +      "th.fs%srd\t%%z1,%%0"
> +    },
> +    {
> +      "th.fl%srb\t%%0,%%1",
> +      "th.fl%srh\t%%0,%%1",
> +      "th.fl%srw\t%%0,%%1",
> +      "th.fl%srd\t%%0,%%1"
> +    }
> +  };
> +
> +  snprintf (buf, sizeof (buf), insn[ldr][index], uindex ? "u" : "");
> +
> +  return buf;
> +}
> +
>  /* Emit an instruction of the form (set TARGET SRC).  */
>
>  static rtx
> @@ -2739,7 +2777,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int 
> outer_code, int opno ATTRIBUTE_UN
>         }
>        /* bit extraction pattern (xtheadmemidx, xtheadfmemidx).  */
>        if (outer_code == SET
> -         && TARGET_XTHEADMEMIDX)
> +         && (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX))
>         {
>           *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
>           return true;
> @@ -3071,6 +3109,20 @@ riscv_split_64bit_move_p (rtx dest, rtx src)
>    if (TARGET_64BIT)
>      return false;
>
> +  if (TARGET_XTHEADFMEMIDX)
> +    {
> +      if (MEM_P (src) && SCALAR_FLOAT_MODE_P (GET_MODE (src))
> +         && riscv_legitimize_address_index_p (XEXP (src, 0),
> +                                              GET_MODE (src), false)
> +         && FP_REG_RTX_P (dest))
> +       return false;
> +      if (MEM_P (dest) && SCALAR_FLOAT_MODE_P (GET_MODE (dest))
> +         && riscv_legitimize_address_index_p (XEXP (dest, 0),
> +                                              GET_MODE (dest), false)
> +         && FP_REG_RTX_P (src))
> +       return false;
> +    }
> +
>    /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case
>       of zeroing an FPR with FCVT.D.W.  */
>    if (TARGET_DOUBLE_FLOAT
> @@ -3269,6 +3321,12 @@ riscv_output_move (rtx dest, rtx src)
>
>        if (dest_code == MEM)
>         {
> +         const char *insn = NULL;
> +         insn = riscv_output_move_index_float (XEXP (dest, 0),
> +                                               GET_MODE (dest), false);
> +         if (insn)
> +           return insn;
> +
>           switch (width)
>             {
>             case 2:
> @@ -3284,6 +3342,12 @@ riscv_output_move (rtx dest, rtx src)
>      {
>        if (src_code == MEM)
>         {
> +         const char *insn = NULL;
> +         insn = riscv_output_move_index_float (XEXP (src, 0),
> +                                               GET_MODE (src), true);
> +         if (insn)
> +           return insn;
> +
>           switch (width)
>             {
>             case 2:
> diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
> index 199bb30162e..13764d60257 100644
> --- a/gcc/config/riscv/riscv.h
> +++ b/gcc/config/riscv/riscv.h
> @@ -535,7 +535,7 @@ enum reg_class
>     factor or added to another register (as well as added to a
>     displacement).  */
>
> -#define INDEX_REG_CLASS ((TARGET_XTHEADMEMIDX) ? \
> +#define INDEX_REG_CLASS ((TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) ? \
>                         GR_REGS : NO_REGS)
>
>  /* We generally want to put call-clobbered registers ahead of
> @@ -707,7 +707,7 @@ typedef struct {
>  /* Addressing modes, and classification of registers for them.  */
>
>  #define REGNO_OK_FOR_INDEX_P(REGNO) \
> -  ((TARGET_XTHEADMEMIDX) ? \
> +  ((TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) ? \
>    riscv_regno_mode_ok_for_base_p (REGNO, VOIDmode, 1) : 0)
>
>  #define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
> diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
> index df31a1fffff..9d0207b8d6f 100644
> --- a/gcc/config/riscv/riscv.md
> +++ b/gcc/config/riscv/riscv.md
> @@ -1866,6 +1866,20 @@ (define_insn "*movsf_hardfloat"
>              "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
>     (set_attr "mode" "SF")])
>
> +(define_insn "*movsf_hardfloat"
> +  [(set (match_operand:SF 0
> +       "nonimmediate_operand" "=f,f,f,m,Qmx,*f,*r,  *r,*r,*Qmx")
> +       (match_operand:SF 1
> +       "move_operand" " f,G,m,f,G,*r,*f,*G*r,*Qmx,*r"))]
> +  "!TARGET_64BIT
> +   && TARGET_XTHEADFMEMIDX
> +   && (register_operand (operands[0], SFmode)
> +       || reg_or_0_operand (operands[1], SFmode))"
> +  { return riscv_output_move (operands[0], operands[1]); }
> +  [(set_attr "move_type"
> +             "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
> +   (set_attr "mode" "SF")])
> +

Plz move to thead.md and named with prefix *th

>  (define_insn "*movsf_softfloat"
>    [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m")
>         (match_operand:SF 1 "move_operand"         " Gr,m,r"))]
> @@ -1900,6 +1914,20 @@ (define_insn "*movdf_hardfloat_rv32"
>              "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
>     (set_attr "mode" "DF")])
>
> +(define_insn "*movdf_hardfloat_rv32"
> +  [(set (match_operand:DF 0
> +       "nonimmediate_operand" "=f,f,f,m,Qmx,  *r,*r,*Qmx")
> +       (match_operand:DF 1
> +       "move_operand" " f,G,m,f,G,*r*G,*Qmx,*r"))]
> +  "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
> +   && TARGET_XTHEADFMEMIDX
> +   && (register_operand (operands[0], DFmode)
> +       || reg_or_0_operand (operands[1], DFmode))"
> +  { return riscv_output_move (operands[0], operands[1]); }
> +  [(set_attr "move_type"
> +            "fmove,mtc,fpload,fpstore,store,move,load,store")
> +   (set_attr "mode" "DF")])
> +

Ditto

Reply via email to