public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/meissner/heads/dmf001)] Add initial __dmr support.
@ 2022-10-18 17:42 Michael Meissner
0 siblings, 0 replies; only message in thread
From: Michael Meissner @ 2022-10-18 17:42 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:9048ade6cd6d4938e9749f0b764c4ab41d88c017
commit 9048ade6cd6d4938e9749f0b764c4ab41d88c017
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Tue Oct 18 13:42:19 2022 -0400
Add initial __dmr support.
2022-10-18 Michael Meissner <meissner@linux.ibm.com>
gcc/
* config/rs6000/mma.md (UNSPEC_DMF_INSERT512_UPPER): New unspec.
(UNSPEC_DMF_INSERT512_LOWER): Likewise.
(UNSPEC_DMF_EXTRACT512): Likewise.
(UNSPEC_DMR_RELOAD_FROM_MEMORY): Likewise.
(UNSPEC_DMR_RELOAD_TO_MEMORY): Likewise.
(movtdo): New expander and define_insn_and_split.
(movtdo_insert512_upper): New insn.
(movtdo_insert512_lower): Likewise.
(movtdo_extract512): Likewise.
(reload_dmf_from_memory): Likewise.
(reload_dmf_to_memory): Likewise.
* config/rs6000/rs6000-builtin.cc (rs6000_type_string): Add __dmr
support.
(rs6000_init_builtins): Likewise.
* config/rs6000/rs6000.cc (rs6000_hard_regno_mode_ok_uncached): Enable
TDOmode in DMF registers.
(rs6000_init_hard_regno_mode_ok): Add __dmr support.
(rs6000_secondary_reload_memory): Likewise.
(rs6000_secondary_reload_simple_move): Likewise.
Diff:
---
gcc/config/rs6000/mma.md | 152 ++++++++++++++++++++++++++++++++++++
gcc/config/rs6000/rs6000-builtin.cc | 13 +++
gcc/config/rs6000/rs6000.cc | 19 ++++-
3 files changed, 183 insertions(+), 1 deletion(-)
diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
index f068dd58c03..b5fca6ef712 100644
--- a/gcc/config/rs6000/mma.md
+++ b/gcc/config/rs6000/mma.md
@@ -92,6 +92,11 @@
UNSPEC_MMA_XXMFACC
UNSPEC_MMA_XXMTACC
UNSPEC_MMA_ASSEMBLE_ACC_DMF
+ UNSPEC_DMF_INSERT512_UPPER
+ UNSPEC_DMF_INSERT512_LOWER
+ UNSPEC_DMF_EXTRACT512
+ UNSPEC_DMR_RELOAD_FROM_MEMORY
+ UNSPEC_DMR_RELOAD_TO_MEMORY
])
(define_c_enum "unspecv"
@@ -864,3 +869,150 @@
[(set_attr "type" "mma")
(set_attr "prefixed" "yes")
(set_attr "isa" "dmf,not_dmf,not_dmf")])
+
+\f
+;; TDOmode (i.e. __dmr).
+(define_expand "movtdo"
+ [(set (match_operand:TDO 0 "nonimmediate_operand")
+ (match_operand:TDO 1 "input_operand"))]
+ "TARGET_DMF"
+{
+ rs6000_emit_move (operands[0], operands[1], TDOmode);
+ DONE;
+})
+
+(define_insn_and_split "*movtdo"
+ [(set (match_operand:TDO 0 "nonimmediate_operand" "=wa,m,wa,wD,wD,wa")
+ (match_operand:TDO 1 "input_operand" "m,wa,wa,wa,wD,wD"))]
+ "TARGET_DMF
+ && (gpc_reg_operand (operands[0], TDOmode)
+ || gpc_reg_operand (operands[1], TDOmode))"
+ "@
+ #
+ #
+ #
+ #
+ dmmr %0,%1
+ #"
+ "&& reload_completed
+ && (!dmf_operand (operands[0], TDOmode) || !dmf_operand (operands[1], TDOmode))"
+ [(const_int 0)]
+{
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+
+ if (REG_P (op0) && REG_P (op1))
+ {
+ int regno0 = REGNO (op0);
+ int regno1 = REGNO (op1);
+
+ if (DMF_REGNO_P (regno0) && VSX_REGNO_P (regno1))
+ {
+ rtx op1_upper = gen_rtx_REG (XOmode, regno1);
+ rtx op1_lower = gen_rtx_REG (XOmode, regno1 + 4);
+ emit_insn (gen_movtdo_insert512_upper (op0, op1_upper));
+ emit_insn (gen_movtdo_insert512_lower (op0, op0, op1_lower));
+ DONE;
+ }
+
+ else if (VSX_REGNO_P (regno0) && DMF_REGNO_P (regno1))
+ {
+ rtx op0_upper = gen_rtx_REG (XOmode, regno0);
+ rtx op0_lower = gen_rtx_REG (XOmode, regno0 + 4);
+ emit_insn (gen_movtdo_extract512 (op0_upper, op1, const0_rtx));
+ emit_insn (gen_movtdo_extract512 (op0_lower, op1, const1_rtx));
+ DONE;
+ }
+ }
+
+ rs6000_split_multireg_move (operands[0], operands[1]);
+ DONE;
+}
+ [(set_attr "type" "vecload,vecstore,vecmove,vecmove,vecmove,vecmove")
+ (set_attr "length" "*,*,32,8,*,8")
+ (set_attr "max_prefixed_insns" "4,4,*,*,*,*")])
+
+;; Move from VSX registers to DMR registers via two insert 512 bit
+;; instructions.
+(define_insn "movtdo_insert512_upper"
+ [(set (match_operand:TDO 0 "dmf_operand" "=wD")
+ (unspec:TDO [(match_operand:XO 1 "vsx_register_operand" "wa")]
+ UNSPEC_DMF_INSERT512_UPPER))]
+ "TARGET_DMF"
+ "dmxxinstdmr512 %0,%1,%Y1,0"
+ [(set_attr "type" "mma")])
+
+(define_insn "movtdo_insert512_lower"
+ [(set (match_operand:TDO 0 "dmf_operand" "=wD")
+ (unspec:TDO [(match_operand:TDO 1 "dmf_operand" "0")
+ (match_operand:XO 2 "vsx_register_operand" "wa")]
+ UNSPEC_DMF_INSERT512_LOWER))]
+ "TARGET_DMF"
+ "dmxxinstdmr512 %0,%2,%Y2,1"
+ [(set_attr "type" "mma")])
+
+;; Move from DMR registers to VSX registers via two extract 512 bit
+;; instructions.
+(define_insn "movtdo_extract512"
+ [(set (match_operand:XO 0 "vsx_register_operand" "=wa")
+ (unspec:XO [(match_operand:TDO 1 "dmf_operand" "wD")
+ (match_operand 2 "const_0_to_1_operand" "n")]
+ UNSPEC_DMF_EXTRACT512))]
+ "TARGET_DMF"
+ "dmxxextfdmr512 %0,%Y0,%1,%2"
+ [(set_attr "type" "mma")])
+
+;; Reload DMF registers from memory
+(define_insn_and_split "reload_dmf_from_memory"
+ [(set (match_operand:TDO 0 "dmf_operand" "=wD")
+ (unspec:TDO [(match_operand:TDO 1 "memory_operand" "m")]
+ UNSPEC_DMR_RELOAD_FROM_MEMORY))
+ (clobber (match_operand:XO 2 "vsx_register_operand" "=wa"))]
+ "TARGET_DMF"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rtx dest = operands[0];
+ rtx src = operands[1];
+ rtx tmp = operands[2];
+ rtx mem_upper = adjust_address (src, XOmode, BYTES_BIG_ENDIAN ? 0 : 32);
+ rtx mem_lower = adjust_address (src, XOmode, BYTES_BIG_ENDIAN ? 32 : 0);
+
+ emit_move_insn (tmp, mem_upper);
+ emit_insn (gen_movtdo_insert512_upper (dest, tmp));
+
+ emit_move_insn (tmp, mem_lower);
+ emit_insn (gen_movtdo_insert512_lower (dest, dest, tmp));
+ DONE;
+}
+ [(set_attr "length" "16")
+ (set_attr "max_prefixed_insns" "2")
+ (set_attr "type" "vecload")])
+
+;; Reload DMF registers to memory
+(define_insn_and_split "reload_dmf_to_memory"
+ [(set (match_operand:TDO 0 "memory_operand" "=m")
+ (unspec:TDO [(match_operand:TDO 1 "dmf_operand" "wD")]
+ UNSPEC_DMR_RELOAD_TO_MEMORY))
+ (clobber (match_operand:XO 2 "vsx_register_operand" "=wa"))]
+ "TARGET_DMF"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rtx dest = operands[0];
+ rtx src = operands[1];
+ rtx tmp = operands[2];
+ rtx mem_upper = adjust_address (dest, XOmode, BYTES_BIG_ENDIAN ? 0 : 32);
+ rtx mem_lower = adjust_address (dest, XOmode, BYTES_BIG_ENDIAN ? 32 : 0);
+
+ emit_insn (gen_movtdo_extract512 (tmp, src, const0_rtx));
+ emit_move_insn (mem_upper, tmp);
+
+ emit_insn (gen_movtdo_extract512 (tmp, src, const1_rtx));
+ emit_move_insn (mem_lower, tmp);
+ DONE;
+}
+ [(set_attr "length" "16")
+ (set_attr "max_prefixed_insns" "2")])
diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index 90ab39dc258..61cbaab908d 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -495,6 +495,8 @@ const char *rs6000_type_string (tree type_node)
return "__vector_pair";
else if (type_node == vector_quad_type_node)
return "__vector_quad";
+ else if (type_node == dmr_type_node)
+ return "__dmr";
return "unknown";
}
@@ -781,6 +783,17 @@ rs6000_init_builtins (void)
t = build_qualified_type (vector_quad_type_node, TYPE_QUAL_CONST);
ptr_vector_quad_type_node = build_pointer_type (t);
+ dmr_type_node = make_node (OPAQUE_TYPE);
+ SET_TYPE_MODE (dmr_type_node, TDOmode);
+ TYPE_SIZE (dmr_type_node) = bitsize_int (GET_MODE_BITSIZE (TDOmode));
+ TYPE_PRECISION (dmr_type_node) = GET_MODE_BITSIZE (TDOmode);
+ TYPE_SIZE_UNIT (dmr_type_node) = size_int (GET_MODE_SIZE (TDOmode));
+ SET_TYPE_ALIGN (dmr_type_node, 512);
+ TYPE_USER_ALIGN (dmr_type_node) = 0;
+ lang_hooks.types.register_builtin_type (dmr_type_node, "__dmr");
+ t = build_qualified_type (dmr_type_node, TYPE_QUAL_CONST);
+ ptr_dmr_type_node = build_pointer_type (t);
+
tdecl = add_builtin_type ("__bool char", bool_char_type_node);
TYPE_NAME (bool_char_type_node) = tdecl;
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index cf6f70a148b..c29cfd4ce50 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -1888,7 +1888,7 @@ rs6000_hard_regno_mode_ok_uncached (int regno, machine_mode mode)
if (!TARGET_DMF)
return 0;
- if (DMF_REGNO_P (regno) && 0)
+ if (DMF_REGNO_P (regno))
return 1;
if (FP_REGNO_P (regno))
@@ -3234,6 +3234,12 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
}
}
+ if (TARGET_DMF)
+ {
+ reg_addr[TDOmode].reload_load = CODE_FOR_reload_dmf_from_memory;
+ reg_addr[TDOmode].reload_store = CODE_FOR_reload_dmf_to_memory;
+ }
+
/* Precalculate HARD_REGNO_NREGS. */
for (r = 0; HARD_REGISTER_NUM_P (r); ++r)
for (m = 0; m < NUM_MACHINE_MODES; ++m)
@@ -12164,6 +12170,10 @@ rs6000_secondary_reload_memory (rtx addr,
addr_mask = (reg_addr[mode].addr_mask[RELOAD_REG_VMX]
& ~RELOAD_REG_AND_M16);
+ /* DMR registers don't support loads or stores. */
+ else if (rclass == DMF_REGS)
+ return -1;
+
/* If the register allocator hasn't made up its mind yet on the register
class to use, settle on defaults to use. */
else if (rclass == NO_REGS)
@@ -12492,6 +12502,13 @@ rs6000_secondary_reload_simple_move (enum rs6000_reg_type to_type,
|| (to_type == SPR_REG_TYPE && from_type == GPR_REG_TYPE)))
return true;
+ /* We can transfer between VSX registers and DMR registers without needing
+ extra registers. */
+ if (TARGET_DMF && (mode == XOmode || mode == TDOmode)
+ && ((to_type == DMF_REG_TYPE && from_type == VSX_REG_TYPE)
+ || (to_type == VSX_REG_TYPE && from_type == DMF_REG_TYPE)))
+ return true;
+
return false;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-10-18 17:42 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-18 17:42 [gcc(refs/users/meissner/heads/dmf001)] Add initial __dmr support Michael Meissner
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).