Ping. Please review.

On Thu, 2026-08-27 at 23:00 +0530, Avinash Jayakar wrote:
> This patch introduces a new mode called QDOmode which is a 256 byte
> opaque mode that maps to __dmr2048 type. The sha3hash instructions
> takes
> a pair of dense math registers, therefore we need this type for those
> builtins.
> 
> The DMR pair register maps to even numbered pair of consecutive DMR
> register. For example, the DMR pair register 2 represents 2 DMR
> registers 2 and 3.
> 
> movqdo pattern has been implemented, which splits the 2048 bit moves
> into smalled 1024 bit tdo moves after the reload pass is completed.
> 
> 2026-08-27  Avinash Jayakar  <[email protected]>
> 
> gcc/ChangeLog:
>       * config/rs6000/mma.md (movqdo): New define_expand.
>       (*movqdo): New define_insn_and_split
>       * config/rs6000/rs6000-builtin.cc (rs6000_type_string): Add
> __dmr2048.
>       (rs6000_init_builtins): Register dmr2048 type.
>       (rs6000_gimple_fold_mma_builtin): Handle QDOmode.
>       * config/rs6000/rs6000-call.cc (rs6000_return_in_memory):
> Allow QDOmode.
>       (rs6000_function_arg): Likewise.
>       * config/rs6000/rs6000-gen-builtins.cc (enum basetype): Add
> DMR2048.
>       (match_type): Likewise.
>       (complete_vector_type): Likewise.
>       * config/rs6000/rs6000-modes.def: Define QDO mode.
>       * config/rs6000/rs6000.cc
> (rs6000_hard_regno_mode_ok_uncached): Allow
>       even number DMR regno for QDOmode.
>       (rs6000_modes_tieable_p): Do not allow QDO with other mode.
>       (rs6000_debug_reg_global): Add QDOmode.
>       (rs6000_setup_reg_addr_masks): Allow QDOmode.
>       (reg_offset_addressing_ok_p): QDOmode return TARGET_DMF.
>       (rs6000_emit_move): Do not allow QDO mode to set to
> constants.
>       (rs6000_secondary_reload_simple_move): Allow QDOmode.
>       (rs6000_preferred_reload_class): QDOmode prefers DMR_REGS.
>       (rs6000_mangle_type): Add __dmr2048 type.
>       (rs6000_dmr_register_move_cost): QDOmode move cost is double
> of TDOmode.
>       (rs6000_register_move_cost): Allow QDOmode.
>       (rs6000_split_multireg_move): Likewise.
>       (rs6000_invalid_conversion): Handle QDOmode.
>       * config/rs6000/rs6000.h (VECTOR_ALIGNMENT_P): True if mode
> is QDOmode.
>       (enum rs6000_builtin_type_index): Add dmr2048 and its ptr
> type.
>       (dmr2048_type_node): Define __dmr2048 node.
>       (ptr_dmr2048_type_node): Define pointer type for __dmr2048
> node.
> ---
>  gcc/config/rs6000/mma.md                 | 57 ++++++++++++++++
>  gcc/config/rs6000/rs6000-builtin.cc      | 17 +++++
>  gcc/config/rs6000/rs6000-call.cc         | 10 +--
>  gcc/config/rs6000/rs6000-gen-builtins.cc | 17 ++++-
>  gcc/config/rs6000/rs6000-modes.def       |  3 +-
>  gcc/config/rs6000/rs6000.cc              | 82 ++++++++++++++++++----
> --
>  gcc/config/rs6000/rs6000.h               |  7 +-
>  7 files changed, 166 insertions(+), 27 deletions(-)
> 
> diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
> index f5085cd967e..7946ec88ae3 100644
> --- a/gcc/config/rs6000/mma.md
> +++ b/gcc/config/rs6000/mma.md
> @@ -662,6 +662,63 @@ (define_insn_and_split "*movtdo"
>    gcc_unreachable ();
>  })
>  
> +;; QDO (2048-bit dense-math pair) move expander.
> +;; Split into 2 TDO moves for the even and odd DMR.
> +(define_expand "movqdo"
> +  [(set (match_operand:QDO 0 "nonimmediate_operand")
> +     (match_operand:QDO 1 "input_operand"))]
> +  "TARGET_DMF"
> +{
> +  rs6000_emit_move (operands[0], operands[1], QDOmode);
> +  DONE;
> +})
> +
> +(define_insn_and_split "*movqdo"
> +  [(set (match_operand:QDO 0 "nonimmediate_operand"
> "=wa,m,wa,wD,wa,wD")
> +     (match_operand:QDO 1 "input_operand" "m,wa,wa,wD,wD,wa"))]
> +  "TARGET_DMF
> +   && (gpc_reg_operand (operands[0], QDOmode)
> +       || gpc_reg_operand (operands[1], QDOmode))"
> +  "#"
> +  "reload_completed"
> +  [(const_int 0)]
> +{
> +  rtx dst = operands[0];
> +  rtx src = operands[1];
> +
> +  if (REG_P (dst) && MEM_P (src))
> +    {
> +      rtx tdo1 = gen_rtx_REG (TDOmode, REGNO (dst));
> +      rtx tdo2 = gen_rtx_REG (TDOmode, REGNO (dst) + 8);
> +      emit_insn (gen_move_insn (tdo1, adjust_address (src, TDOmode,
> 0)));
> +      emit_insn (gen_move_insn (tdo2, adjust_address (src, TDOmode,
> 128)));
> +      DONE;
> +    }
> +  else if (REG_P (src) && MEM_P (dst))
> +    {
> +      rtx tdo1 = gen_rtx_REG (TDOmode, REGNO (src));
> +      rtx tdo2 = gen_rtx_REG (TDOmode, REGNO (src) + 8);
> +      emit_insn (gen_move_insn (adjust_address (dst, TDOmode, 0),
> tdo1));
> +      emit_insn (gen_move_insn (adjust_address (dst, TDOmode, 128),
> tdo2));
> +      DONE;
> +    }
> +  else if (REG_P (src) && REG_P (dst))
> +    {
> +      rtx stdo1 = gen_rtx_REG (TDOmode, REGNO (src));
> +      rtx stdo2 = gen_rtx_REG (TDOmode,
> +                            REGNO (src)
> +                            + (VSX_REGNO_P (REGNO (src)) ? 8 :
> 1));
> +      rtx dtdo1 = gen_rtx_REG (TDOmode, REGNO (dst));
> +      rtx dtdo2 = gen_rtx_REG (TDOmode,
> +                            REGNO (dst)
> +                            + (VSX_REGNO_P (REGNO (dst)) ? 8 :
> 1));
> +      emit_insn (gen_move_insn (dtdo1, stdo1));
> +      emit_insn (gen_move_insn (dtdo2, stdo2));
> +      DONE;
> +    }
> +  gcc_unreachable ();
> +})
> +
>  
>  (define_insn_and_split "reload_tdo_load"
>    [(set (match_operand:TDO 0 "dmr_register_operand" "=wD")
> diff --git a/gcc/config/rs6000/rs6000-builtin.cc
> b/gcc/config/rs6000/rs6000-builtin.cc
> index 50c18ddee8f..7ad2d932f00 100644
> --- a/gcc/config/rs6000/rs6000-builtin.cc
> +++ b/gcc/config/rs6000/rs6000-builtin.cc
> @@ -519,6 +519,8 @@ const char *rs6000_type_string (tree type_node)
>      return "__vector_quad";
>    else if (type_node == dmr1024_type_node)
>      return "__dmr1024";
> +  else if (type_node == dmr2048_type_node)
> +    return "__dmr2048";
>  
>    return "unknown";
>  }
> @@ -835,6 +837,18 @@ rs6000_init_builtins (void)
>    t = build_qualified_type (dmr1024_type_node, TYPE_QUAL_CONST);
>    ptr_dmr1024_type_node = build_pointer_type (t);
>  
> +  /* QDOmode (2048-bit dmr pair).  Use 512-bit alignment like
> dmr1024.  */
> +  dmr2048_type_node = make_node (OPAQUE_TYPE);
> +  SET_TYPE_MODE (dmr2048_type_node, QDOmode);
> +  TYPE_SIZE (dmr2048_type_node) = bitsize_int (GET_MODE_BITSIZE
> (QDOmode));
> +  TYPE_PRECISION (dmr2048_type_node) = GET_MODE_BITSIZE (QDOmode);
> +  TYPE_SIZE_UNIT (dmr2048_type_node) = size_int (GET_MODE_SIZE
> (QDOmode));
> +  SET_TYPE_ALIGN (dmr2048_type_node, 512);
> +  TYPE_USER_ALIGN (dmr2048_type_node) = 0;
> +  lang_hooks.types.register_builtin_type (dmr2048_type_node,
> "__dmr2048");
> +  t = build_qualified_type (dmr2048_type_node, TYPE_QUAL_CONST);
> +  ptr_dmr2048_type_node = build_pointer_type (t);
> +
>    tdecl = add_builtin_type ("__bool char", bool_char_type_node);
>    TYPE_NAME (bool_char_type_node) = tdecl;
>  
> @@ -1331,6 +1345,9 @@ rs6000_gimple_fold_mma_builtin
> (gimple_stmt_iterator *gsi,
>      case TDOmode:
>        lhs_type = dmr1024_type_node;
>        break;
> +    case QDOmode:
> +      lhs_type = dmr2048_type_node;
> +      break;
>      case XOmode:
>        lhs_type = vector_quad_type_node;
>        break;
> diff --git a/gcc/config/rs6000/rs6000-call.cc
> b/gcc/config/rs6000/rs6000-call.cc
> index 0da2c1f6071..a33d38c68dd 100644
> --- a/gcc/config/rs6000/rs6000-call.cc
> +++ b/gcc/config/rs6000/rs6000-call.cc
> @@ -439,7 +439,8 @@ rs6000_return_in_memory (const_tree type,
> const_tree fntype ATTRIBUTE_UNUSED)
>        && TREE_TYPE (cfun->decl) == fntype
>        && (TYPE_MODE (type) == OOmode
>          || TYPE_MODE (type) == XOmode
> -        || TYPE_MODE (type) == TDOmode))
> +        || TYPE_MODE (type) == TDOmode
> +        || TYPE_MODE (type) == QDOmode))
>      {
>        /* Record we have now handled function CFUN, so the next time
> we
>        are called, we do not re-report the same error.  */
> @@ -447,7 +448,8 @@ rs6000_return_in_memory (const_tree type,
> const_tree fntype ATTRIBUTE_UNUSED)
>        if (TYPE_CANONICAL (type) != NULL_TREE)
>       type = TYPE_CANONICAL (type);
>        const char *type_class =
> -      (TYPE_MODE (type) == TDOmode) ? "Dense Math" : "MMA";
> +      (TYPE_MODE (type) == TDOmode || TYPE_MODE (type) ==
> QDOmode)
> +      ? "Dense Math" : "MMA";
>        error ("invalid use of %s type %qs as a function return
> value",
>            type_class,
>            IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
> @@ -1637,12 +1639,12 @@ rs6000_function_arg (cumulative_args_t cum_v,
> const function_arg_info &arg)
>    int n_elts;
>  
>    /* We do not allow Dense Math/MMA types being used as function
> arguments.  */
> -  if (mode == OOmode || mode == XOmode || mode == TDOmode)
> +  if (mode == OOmode || mode == XOmode || mode == TDOmode || mode ==
> QDOmode)
>      {
>        if (TYPE_CANONICAL (type) != NULL_TREE)
>       type = TYPE_CANONICAL (type);
>        const char *type_class =
> -      (mode == TDOmode) ? "Dense Math" : "MMA";
> +     (mode == TDOmode || mode == QDOmode) ? "Dense Math" : "MMA";
>        error ("invalid use of %s operand of type %qs as a function
> parameter",
>            type_class,
>            IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
> diff --git a/gcc/config/rs6000/rs6000-gen-builtins.cc
> b/gcc/config/rs6000/rs6000-gen-builtins.cc
> index 08068ba78fd..87273d1ef9c 100644
> --- a/gcc/config/rs6000/rs6000-gen-builtins.cc
> +++ b/gcc/config/rs6000/rs6000-gen-builtins.cc
> @@ -340,7 +340,8 @@ enum basetype
>    BT_IBM128,
>    BT_VPAIR,
>    BT_VQUAD,
> -  BT_DMR
> +  BT_DMR,
> +  BT_DMR2048
>  };
>  
>  /* Ways in which a const int value can be restricted.  RES_BITS
> indicates
> @@ -562,6 +563,7 @@ static typemap type_map[] =
>      { "pv16qi",              "ptr_V16QI" },
>      { "pv1poi",              "ptr_vector_pair" },
>      { "pv1pxi",              "ptr_vector_quad" },
> +    { "pv1qdoi",     "ptr_dmr2048" },
>      { "pv1tdoi",     "ptr_dmr1024" },
>      { "pv1ti",               "ptr_V1TI" },
>      { "pv2df",               "ptr_V2DF" },
> @@ -593,6 +595,7 @@ static typemap type_map[] =
>      { "v16qi",               "V16QI" },
>      { "v1poi",               "vector_pair" },
>      { "v1pxi",               "vector_quad" },
> +    { "v1qdoi",      "dmr2048" },
>      { "v1tdoi",      "dmr1024" },
>      { "v1ti",                "V1TI" },
>      { "v2df",                "V2DF" },
> @@ -1080,6 +1083,7 @@ match_type (typeinfo *typedata, int voidok)
>         v256  __vector_pair
>         v512  __vector_quad
>         dmr1024       __dmr1024
> +       dmr2048       __dmr2048
>  
>       For simplicity, We don't support "short int" and "long long
> int".
>       We don't currently support a <basetype> of "_Float16". 
> "signed"
> @@ -1268,6 +1272,13 @@ match_type (typeinfo *typedata, int voidok)
>        handle_pointer (typedata);
>        return 1;
>      }
> +  else if (!strcmp (token, "dmr2048"))
> +    {
> +      typedata->isvector = 1;
> +      typedata->base = BT_DMR2048;
> +      handle_pointer (typedata);
> +      return 1;
> +    }
>    else if (!strcmp (token, "signed"))
>      typedata->issigned = 1;
>    else if (!strcmp (token, "unsigned"))
> @@ -1578,6 +1589,10 @@ complete_vector_type (typeinfo *typeptr, char
> *buf, int *bufi)
>        memcpy (&buf[*bufi], "1tdoi", 5);
>        *bufi += 5;
>        break;
> +    case BT_DMR2048:
> +      memcpy (&buf[*bufi], "1qdoi", 5);
> +      *bufi += 5;
> +      break;
>      default:
>        diag (pos, "unhandled basetype %d.\n", typeptr->base);
>        exit (1);
> diff --git a/gcc/config/rs6000/rs6000-modes.def
> b/gcc/config/rs6000/rs6000-modes.def
> index 0ad326751c4..899c08bf061 100644
> --- a/gcc/config/rs6000/rs6000-modes.def
> +++ b/gcc/config/rs6000/rs6000-modes.def
> @@ -76,7 +76,8 @@ VECTOR_MODE (INT, SI, 2);     /*                
> V2SI  */
>     combination.  */
>  PARTIAL_INT_MODE (TI, 128, PTI);
>  
> -/* Modes used by __vector_pair, __vector_quad and __dmr1024.  */
> +/* Modes used by __vector_pair, __vector_quad, __dmr1024 and
> __dmr2048.  */
>  OPAQUE_MODE (OO, 32);
>  OPAQUE_MODE (XO, 64);
>  OPAQUE_MODE (TDO, 128);
> +OPAQUE_MODE (QDO, 256);
> diff --git a/gcc/config/rs6000/rs6000.cc
> b/gcc/config/rs6000/rs6000.cc
> index 99555988913..a940d27faae 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -1869,7 +1869,8 @@ rs6000_hard_regno_mode_ok_uncached (int regno,
> machine_mode mode)
>      mode = GET_MODE_INNER (mode);
>  
>    /* No other types other than XOmode or TDOmode can go in DMRs.  */
> -  if (DMR_REGNO_P (regno) && !(mode ==XOmode || mode == TDOmode))
> +  if (DMR_REGNO_P (regno)
> +      && !(mode ==XOmode || mode == TDOmode || mode == QDOmode))
>      return 0;
>  
>    /* TDOmode value can be held in either 1 DMR register or 8 VSX
> @@ -1884,6 +1885,18 @@ rs6000_hard_regno_mode_ok_uncached (int regno,
> machine_mode mode)
>        else
>       return 0;
>      }
> +  if (mode == QDOmode)
> +    {
> +      if (TARGET_DMF)
> +     return ((DMR_REGNO_P (regno)
> +              && DMR_REGNO_P (last_regno)
> +              && ((regno - FIRST_DMR_REGNO) % 2 == 0))
> +             || (VSX_REGNO_P (regno)
> +                 && VSX_REGNO_P (last_regno)
> +                 && (regno & 1) == 0));
> +      else
> +     return 0;
> +    }
>  
>    /* Vector pair modes need even/odd VSX register pairs.  Only allow
> vector
>       registers.  */
> @@ -2011,8 +2024,9 @@ static bool
>  rs6000_modes_tieable_p (machine_mode mode1, machine_mode mode2)
>  {
>    if (mode1 == PTImode || mode1 == OOmode || mode1 == XOmode
> -      || mode1 == TDOmode || mode2 == PTImode || mode2 == OOmode
> -      || mode2 == XOmode || mode2 == TDOmode)
> +      || mode1 == TDOmode || mode1 == QDOmode
> +      || mode2 == PTImode || mode2 == OOmode
> +      || mode2 == XOmode || mode2 == TDOmode || mode2 == QDOmode)
>      return mode1 == mode2;
>  
>    if (ALTIVEC_OR_VSX_VECTOR_MODE (mode1))
> @@ -2304,6 +2318,7 @@ rs6000_debug_reg_global (void)
>      OOmode,
>      XOmode,
>      TDOmode,
> +    QDOmode,
>      CCmode,
>      CCUNSmode,
>      CCEQmode,
> @@ -2668,7 +2683,8 @@ rs6000_setup_reg_addr_masks (void)
>  
>         if (rc == RELOAD_REG_DMR)
>           {
> -           if (TARGET_DMF && (m2 == XOmode || m2 == TDOmode))
> +           if (TARGET_DMF
> +               && (m2 == XOmode || m2 == TDOmode || m2 ==
> QDOmode))
>               {
>                 addr_mask = RELOAD_REG_VALID;
>                 reg_addr[m].addr_mask[rc] = addr_mask;
> @@ -2779,8 +2795,9 @@ rs6000_setup_reg_addr_masks (void)
>            dmr1024 type can only do offset loads.  */
>         else if ((addr_mask != 0)
>                  && ((TARGET_MMA && (m2 == OOmode || m2 ==
> XOmode))
> -                     || (TARGET_DMF
> -                         && (m2 == TDOmode || m2 == OOmode || m2
> == XOmode))))
> +                    || (TARGET_DMF
> +                        && (m2 == TDOmode || m2 == QDOmode
> +                            || m2 == OOmode || m2 == XOmode))))
>           {
>             addr_mask |= RELOAD_REG_OFFSET;
>             if (rc == RELOAD_REG_FPR || rc == RELOAD_REG_VMX)
> @@ -8756,6 +8773,7 @@ reg_offset_addressing_ok_p (machine_mode mode)
>        return TARGET_MMA || TARGET_DMF;
>  
>      case E_TDOmode:
> +    case E_QDOmode:
>        return TARGET_DMF;
>  
>      case E_SDmode:
> @@ -11317,6 +11335,12 @@ rs6000_emit_move (rtx dest, rtx source,
> machine_mode mode)
>              "__dmr1024");
>        break;
>  
> +    case E_QDOmode:
> +      if (CONST_INT_P (operands[1]))
> +     error ("%qs is an opaque type, and you cannot set it to
> constants",
> +            "__dmr2048");
> +      break;
> +
>      case E_SImode:
>      case E_DImode:
>        /* Use default pattern for address of ELF small data */
> @@ -12783,9 +12807,9 @@ rs6000_secondary_reload_simple_move (enum
> rs6000_reg_type to_type,
>      return true;
>  
>    /* DMRs can be copied to VSX register, and vice versa.  */
> -  if (TARGET_DMF && (mode == XOmode || mode == TDOmode)
> +  if (TARGET_DMF && (mode == XOmode || mode == TDOmode || mode ==
> QDOmode)
>        && ((to_type == DMR_REG_TYPE && from_type == VSX_REG_TYPE)
> -        || (to_type == VSX_REG_TYPE && from_type ==
> DMR_REG_TYPE)))
> +       || (to_type == VSX_REG_TYPE && from_type ==
> DMR_REG_TYPE)))
>      return true;
>  
>    return false;
> @@ -13587,6 +13611,9 @@ rs6000_preferred_reload_class (rtx x, enum
> reg_class rclass)
>        if (mode == TDOmode)
>       return VSX_REGS;
>  
> +      if (mode == QDOmode)
> +     return DMR_REGS;
> +
>        if (GET_MODE_CLASS (mode) == MODE_INT)
>       return GENERAL_REGS;
>      }
> @@ -20806,6 +20833,8 @@ rs6000_mangle_type (const_tree type)
>      return "u13__vector_quad";
>    if (type == dmr1024_type_node)
>      return "u9__dmr1024";
> +  if (type == dmr2048_type_node)
> +    return "u9__dmr2048";
>  
>    /* For all other types, use the default mangling.  */
>    return NULL;
> @@ -22935,6 +22964,10 @@ rs6000_dmr_register_move_cost (machine_mode
> mode, reg_class_t rclass)
>        else if (mode == TDOmode)
>       return base_cost * 2;
>  
> +      /* QDOmode (dmr pair) can be copied in 4 instructions.  */
> +      else if (mode == QDOmode)
> +     return base_cost * 4;
> +
>        else
>       return base_cost * 2 * hard_regno_nregs (FIRST_DMR_REGNO,
> mode);
>      }
> @@ -22964,7 +22997,8 @@ rs6000_register_move_cost (machine_mode mode,
>    to_vsx = reg_class_contents[to] & reg_class_contents[VSX_REGS];
>    from_vsx = reg_class_contents[from] &
> reg_class_contents[VSX_REGS];
>  
> -  if ((mode == TDOmode || mode==XOmode) && from == DMR_REGS && to ==
> DMR_REGS)
> +  if ((mode == TDOmode || mode == XOmode || mode == QDOmode)
> +      && from == DMR_REGS && to == DMR_REGS)
>      ret = 2 * hard_regno_nregs (FIRST_DMR_REGNO, mode);
>  
>    else if (from == DMR_REGS)
> @@ -27625,15 +27659,17 @@ rs6000_split_multireg_move (rtx dst, rtx
> src)
>    /* If we have a vector quad register for MMA or DMR register for
> Dense Math,
>       and this is a load or store, see if we can use vector paired
>       load/stores.  */
> -  if ((mode == XOmode || mode == TDOmode) && (TARGET_MMA ||
> TARGET_DMF)
> +  if ((mode == XOmode || mode == TDOmode || mode == QDOmode)
> +      && (TARGET_MMA || TARGET_DMF)
>        && (MEM_P (dst) || MEM_P (src)))
>      {
>        reg_mode = OOmode;
>        nregs /= 2;
>      }
> -  /* If we have a vector pair/quad mode, split it into two/four
> separate
> -     vectors.  */
> -  else if (mode == OOmode || mode == XOmode || mode == TDOmode)
> +  /* If we have a vector pair/quad/dmr pair mode, split it into
> two/four/eight
> +     separate vectors.  */
> +  else if (mode == OOmode || mode == XOmode || mode == TDOmode
> +        || mode == QDOmode)
>      reg_mode = V1TImode;
>    else if (FP_REGNO_P (reg))
>      reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
> @@ -27685,7 +27721,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
>       below.  This means the last register gets the first memory
>       location.  We also need to be careful of using the right
> register
>       numbers if we are splitting XO to OO.  */
> -  if (mode == OOmode || mode == XOmode || mode == TDOmode)
> +  if (mode == OOmode || mode == XOmode || mode == TDOmode || mode ==
> QDOmode)
>      {
>        nregs = hard_regno_nregs (reg, mode);
>        int reg_mode_nregs = hard_regno_nregs (reg, reg_mode);
> @@ -27823,8 +27859,9 @@ rs6000_split_multireg_move (rtx dst, rtx src)
>        /* Move register range backwards, if we might have destructive
>        overlap.  */
>        int i;
> -      /* XO/OO/TDO are opaque so cannot use subregs. */
> -      if (mode == OOmode || mode == XOmode || mode == TDOmode)
> +      /* XO/OO/TDO/QDO are opaque so cannot use subregs.  */
> +      if (mode == OOmode || mode == XOmode || mode == TDOmode
> +       || mode == QDOmode)
>       {
>         for (i = nregs - 1; i >= 0; i--)
>           {
> @@ -27999,8 +28036,9 @@ rs6000_split_multireg_move (rtx dst, rtx src)
>         if (j == 0 && used_update)
>           continue;
>  
> -       /* XO/OO/TDO are opaque so cannot use subregs. */
> -       if (mode == OOmode || mode == XOmode || mode == TDOmode)
> +       /* XO/OO/TDO/QDO are opaque so cannot use subregs.  */
> +       if (mode == OOmode || mode == XOmode || mode == TDOmode
> +           || mode == QDOmode)
>           {
>             rtx dst_i = gen_rtx_REG (reg_mode, REGNO (dst) + j);
>             rtx src_i = gen_rtx_REG (reg_mode, REGNO (src) + j);
> @@ -29029,8 +29067,8 @@ rs6000_invalid_conversion (const_tree
> fromtype, const_tree totype)
>  
>    if (frommode != tomode)
>      {
> -      /* Do not allow conversions to/from XOmode, OOmode and TDOmode
> -      types.  */
> +      /* Do not allow conversions to/from XOmode, OOmode, TDOmode
> and QDOmode
> +  types.  */
>        if (frommode == XOmode)
>       return N_("invalid conversion from type %<__vector_quad%>");
>        if (tomode == XOmode)
> @@ -29043,6 +29081,10 @@ rs6000_invalid_conversion (const_tree
> fromtype, const_tree totype)
>       return N_("invalid conversion from type %<__dmr1024%>");
>        if (tomode == TDOmode)
>       return N_("invalid conversion to type %<__dmr1024%>");
> +      if (frommode == QDOmode)
> +     return N_("invalid conversion from type %<__dmr2048%>");
> +      if (tomode == QDOmode)
> +     return N_("invalid conversion to type %<__dmr2048%>");
>      }
>  
>    /* Conversion allowed.  */
> diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
> index bcd4c39d24d..16862ded01b 100644
> --- a/gcc/config/rs6000/rs6000.h
> +++ b/gcc/config/rs6000/rs6000.h
> @@ -985,7 +985,8 @@ enum data_align { align_abi, align_opt,
> align_both };
>  /* Modes that are not vectors, but require vector alignment.  Treat
> these like
>     vectors in terms of loads and stores.  */
>  #define
> VECTOR_ALIGNMENT_P(MODE)                                      \
> -  (FLOAT128_VECTOR_P (MODE) || (MODE) == OOmode || (MODE) == XOmode
> || (MODE) == TDOmode)
> +  (FLOAT128_VECTOR_P (MODE) || (MODE) == OOmode || (MODE) ==
> XOmode     \
> +   || (MODE) == TDOmode || (MODE) == QDOmode)
>  
>  #define
> ALTIVEC_VECTOR_MODE(MODE)                                     \
>    ((MODE) ==
> V16QImode                                                     \
> @@ -2277,6 +2278,7 @@ enum rs6000_builtin_type_index
>    RS6000_BTI_vector_pair,     /* unsigned 256-bit types (vector
> pair).  */
>    RS6000_BTI_vector_quad,     /* unsigned 512-bit types (vector
> quad).  */
>    RS6000_BTI_dmr1024,            /* unsigned 1024-bit type
> (dmr1024).  */
> +  RS6000_BTI_dmr2048,            /* unsigned 2048-bit type
> (dmr2048).  */
>    RS6000_BTI_const_ptr_void,     /* const pointer to void */
>    RS6000_BTI_ptr_V16QI,
>    RS6000_BTI_ptr_V1TI,
> @@ -2316,6 +2318,7 @@ enum rs6000_builtin_type_index
>    RS6000_BTI_ptr_vector_pair,
>    RS6000_BTI_ptr_vector_quad,
>    RS6000_BTI_ptr_dmr1024,
> +  RS6000_BTI_ptr_dmr2048,
>    RS6000_BTI_ptr_long_long,
>    RS6000_BTI_ptr_long_long_unsigned,
>    RS6000_BTI_INTPTI,
> @@ -2378,6 +2381,7 @@ enum rs6000_builtin_type_index
>  #define vector_pair_type_node                
> (rs6000_builtin_types[RS6000_BTI_vector_pair])
>  #define vector_quad_type_node                
> (rs6000_builtin_types[RS6000_BTI_vector_quad])
>  #define dmr1024_type_node               
> (rs6000_builtin_types[RS6000_BTI_dmr1024])
> +#define dmr2048_type_node               
> (rs6000_builtin_types[RS6000_BTI_dmr2048])
>  #define pcvoid_type_node             
> (rs6000_builtin_types[RS6000_BTI_const_ptr_void])
>  #define ptr_V16QI_type_node          
> (rs6000_builtin_types[RS6000_BTI_ptr_V16QI])
>  #define ptr_V1TI_type_node           
> (rs6000_builtin_types[RS6000_BTI_ptr_V1TI])
> @@ -2417,6 +2421,7 @@ enum rs6000_builtin_type_index
>  #define ptr_vector_pair_type_node    
> (rs6000_builtin_types[RS6000_BTI_ptr_vector_pair])
>  #define ptr_vector_quad_type_node    
> (rs6000_builtin_types[RS6000_BTI_ptr_vector_quad])
>  #define ptr_dmr1024_type_node           
> (rs6000_builtin_types[RS6000_BTI_ptr_dmr1024])
> +#define ptr_dmr2048_type_node           
> (rs6000_builtin_types[RS6000_BTI_ptr_dmr2048])
>  #define ptr_long_long_integer_type_node      
> (rs6000_builtin_types[RS6000_BTI_ptr_long_long])
>  #define ptr_long_long_unsigned_type_node
> (rs6000_builtin_types[RS6000_BTI_ptr_long_long_unsigned])
>  

Reply via email to