[gcc(refs/users/meissner/heads/work168-tar)] Add support for the TAR register.
Michael Meissner
meissner@gcc.gnu.org
Tue Jun 4 18:26:06 GMT 2024
https://gcc.gnu.org/g:f5177d70ff8945e98334be05bc706e133ec83cd3
commit f5177d70ff8945e98334be05bc706e133ec83cd3
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Tue Jun 4 14:25:29 2024 -0400
Add support for the TAR register.
2024-06-04 Michael Meissner <meissner@linux.ibm.com>
gcc/
* config/rs6000/constraints.md (h constraint): Add TAR register to the
documentation.
(wt constraint): New constraint.
* config/rs6000/rs6000-cpus.def (ISA_3_0_MASKS_SERVER): Document that we
do not explicitly add -mtar for power9.
(OTHER_POWER10_MASKS): Add -mtar.
(POWERPC_MASKS): Likewise.
* config/rs6000/rs6000.cc (rs6000_reg_names): Add TAR register support.
(alt_reg_names): Likewise.
(rs6000_hard_regno_mode_ok_uncached): Likewise.
(rs6000_debug_reg_global): Print the register class that wt maps too.
(rs6000_init_hard_regno_mode_ok): Add TAR register support.
(rs6000_option_override_internal): Restrict -mtar to power9 and above.
(rs6000_conditional_register_usage): Add TAR register support.
(print_operand): Likewise.
(rs6000_debugger_regno): Likewise.
(rs6000_opt_masks): Add support for -mtar.
* config/rs6000/rs6000.h (FIRST_PSEUDO_REGISTER): Add TAR register
support.
(FIXED_REGISTERS): Likewise.
(CALL_REALLY_USED_REGISTERS): Likewise.
(REG_ALLOC_ORDER): Likewise.
(enum reg_class): Likewise.
(REG_CLASS_NAMES): Likewise.
(REG_CLASS_CONTENTS): Likewise.
(enum r6000_reg_class_enum): Add support for the wt constraint.
* config/rs6000/rs6000.md (TAR_REGNO): New constant.
(mov<mode>_internal): Add TAR register support.
(call_indirect_nonlocal_sysv<mode>): Likewise.
(call_value_indirect_nonlocal_sysv<mode>): Likewise.
(call_indirect_aix<mode>): Likewise.
(call_value_indirect_aix<mode>): Likewise.
(call_indirect_elfv2<mode>): Likewise.
(call_indirect_pcrel<mode>): Likewise.
(call_value_indirect_elfv2<mode>): Likewise.
(call_value_indirect_pcrel<mode>): Likewise.
(*sibcall_indirect_nonlocal_sysv<mode>): Likewise.
(sibcall_value_indirect_nonlocal_sysv<mode>): Likewise.
(indirect_jump<mode>): Likewise.
(@indirect_jump<mode>_nospec): Likewise.
(@tablejump<mode>_insn_normal): Likewise.
(@tablejump<mode>_insn_nospec): Likewise.
* config/rs6000/rs6000.opt (-mtar): New option.
gcc/testsuite/
* gcc.target/powerpc/ppc-switch-1.c: Update test for the TAR register.
* gcc.target/powerpc/pr51513.c: Likewise.
* gcc.target/powerpc/safe-indirect-jump-2.c: Likewise.
* gcc.target/powerpc/safe-indirect-jump-3.c: Likewise.
* gcc.target/powerpc/tar-register.c: New test.
Diff:
---
gcc/config/rs6000/constraints.md | 5 ++-
gcc/config/rs6000/rs6000-cpus.def | 7 ++--
gcc/config/rs6000/rs6000.cc | 42 ++++++++++++++++++----
gcc/config/rs6000/rs6000.h | 31 +++++++++-------
gcc/config/rs6000/rs6000.md | 35 +++++++++---------
gcc/config/rs6000/rs6000.opt | 4 +++
gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c | 4 +--
gcc/testsuite/gcc.target/powerpc/pr51513.c | 4 +--
.../gcc.target/powerpc/safe-indirect-jump-2.c | 2 +-
.../gcc.target/powerpc/safe-indirect-jump-3.c | 2 +-
gcc/testsuite/gcc.target/powerpc/tar-register.c | 34 ++++++++++++++++++
11 files changed, 126 insertions(+), 44 deletions(-)
diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
index 369a7b75042..14f0465d7ae 100644
--- a/gcc/config/rs6000/constraints.md
+++ b/gcc/config/rs6000/constraints.md
@@ -57,7 +57,7 @@
"@internal A compatibility alias for @code{wa}.")
(define_register_constraint "h" "SPECIAL_REGS"
- "@internal A special register (@code{vrsave}, @code{ctr}, or @code{lr}).")
+ "@internal A special register (@code{vrsave}, @code{ctr}, @code{lr} or @code{tar}).")
(define_register_constraint "c" "CTR_REGS"
"The count register, @code{ctr}.")
@@ -91,6 +91,9 @@
"@internal Like @code{r}, if @option{-mpowerpc64} is used; otherwise,
@code{NO_REGS}.")
+(define_register_constraint "wt" "rs6000_constraints[RS6000_CONSTRAINT_wt]"
+ "The tar register, @code{tar}.")
+
(define_register_constraint "wx" "rs6000_constraints[RS6000_CONSTRAINT_wx]"
"@internal Like @code{d}, if @option{-mpowerpc-gfxopt} is used; otherwise,
@code{NO_REGS}.")
diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index d625dbeb91f..37366d5e056 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -59,7 +59,8 @@
| OPTION_MASK_P8_FUSION_SIGN)
/* Add ISEL back into ISA 3.0, since it is supposed to be a win. Do not add
- FLOAT128_HW here until we are ready to make -mfloat128 on by default. */
+ FLOAT128_HW here until we are ready to make -mfloat128 on by default. Also
+ do not add -mtar, since it isn't as helpful on power9. */
#define ISA_3_0_MASKS_SERVER ((ISA_2_7_MASKS_SERVER \
| OPTION_MASK_ISEL \
| OPTION_MASK_MODULO \
@@ -80,7 +81,8 @@
#define OTHER_POWER10_MASKS (OPTION_MASK_MMA \
| OPTION_MASK_PCREL \
/* | OPTION_MASK_PCREL_OPT */ \
- | OPTION_MASK_PREFIXED)
+ | OPTION_MASK_PREFIXED \
+ | OPTION_MASK_TAR)
#define ISA_3_1_MASKS_SERVER (ISA_3_0_MASKS_SERVER \
| OPTION_MASK_POWER10 \
@@ -158,6 +160,7 @@
| OPTION_MASK_RECIP_PRECISION \
| OPTION_MASK_SOFT_FLOAT \
| OPTION_MASK_STRICT_ALIGN_OPTIONAL \
+ | OPTION_MASK_TAR \
| OPTION_MASK_VSX)
#endif
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index c2f8096beec..c106e13b8ad 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -1224,8 +1224,8 @@ char rs6000_reg_names[][8] =
"lr", "ctr", "ca", "ap",
/* cr0..cr7 */
"0", "1", "2", "3", "4", "5", "6", "7",
- /* vrsave vscr sfp */
- "vrsave", "vscr", "sfp",
+ /* vrsave vscr sfp, tar */
+ "vrsave", "vscr", "sfp", "tar",
};
#ifdef TARGET_REGNAMES
@@ -1250,8 +1250,8 @@ static const char alt_reg_names[][8] =
"lr", "ctr", "ca", "ap",
/* cr0..cr7 */
"%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
- /* vrsave vscr sfp */
- "vrsave", "vscr", "sfp",
+ /* vrsave vscr sfp, tar */
+ "vrsave", "vscr", "sfp", "tar"
};
#endif
@@ -1948,6 +1948,7 @@ rs6000_hard_regno_mode_ok_uncached (int regno, machine_mode mode)
case VSCR_REGNO:
case LR_REGNO:
case CTR_REGNO:
+ case TAR_REGNO:
{
unsigned reg_size = ((regno == VRSAVE_REGNO || regno == VSCR_REGNO)
? 4
@@ -2334,6 +2335,7 @@ rs6000_debug_reg_global (void)
"vs");
rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
+ rs6000_debug_reg_print (TAR_REGNO, TAR_REGNO, "tar");
rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
@@ -2350,6 +2352,7 @@ rs6000_debug_reg_global (void)
"wa reg_class = %s\n"
"we reg_class = %s\n"
"wr reg_class = %s\n"
+ "wt reg_class = %s\n"
"wx reg_class = %s\n"
"wA reg_class = %s\n"
"\n",
@@ -2358,6 +2361,7 @@ rs6000_debug_reg_global (void)
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_we]],
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wr]],
+ reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wt]],
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wx]],
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wA]]);
@@ -2808,6 +2812,7 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
+ rs6000_regno_regclass[TAR_REGNO] = TAR_REGS;
rs6000_regno_regclass[CA_REGNO] = NO_REGS;
rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
@@ -2827,6 +2832,7 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
reg_class_to_reg_type[(int)VSCR_REGS] = SPR_REG_TYPE;
reg_class_to_reg_type[(int)LINK_REGS] = SPR_REG_TYPE;
reg_class_to_reg_type[(int)CTR_REGS] = SPR_REG_TYPE;
+ reg_class_to_reg_type[(int)TAR_REGS] = SPR_REG_TYPE;
reg_class_to_reg_type[(int)LINK_OR_CTR_REGS] = SPR_REG_TYPE;
reg_class_to_reg_type[(int)CR_REGS] = CR_REG_TYPE;
reg_class_to_reg_type[(int)CR0_REGS] = CR_REG_TYPE;
@@ -3016,6 +3022,10 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
if (TARGET_DIRECT_MOVE_128)
rs6000_constraints[RS6000_CONSTRAINT_we] = VSX_REGS;
+ /* Power9 adds a TAR register that can hold the target of a jump. */
+ if (TARGET_TAR)
+ rs6000_constraints[RS6000_CONSTRAINT_wt] = TAR_REGS;
+
/* Set up the reload helper and direct move functions. */
if (TARGET_VSX || TARGET_ALTIVEC)
{
@@ -4224,6 +4234,15 @@ rs6000_option_override_internal (bool global_init_p)
rs6000_isa_flags &= ~OPTION_MASK_FLOAT128_HW;
}
+ /* If -mtar, make sure we have at least a power9. */
+ if (TARGET_TAR && !TARGET_P9_MISC)
+ {
+ if ((rs6000_isa_flags_explicit & OPTION_MASK_TAR) != 0)
+ error ("%qs requires %qs", "-mtar", "-mcpu=power9");
+
+ rs6000_isa_flags &= ~OPTION_MASK_TAR;
+ }
+
/* Enable -mprefixed by default on power10 systems. */
if (TARGET_POWER10 && (rs6000_isa_flags_explicit & OPTION_MASK_PREFIXED) == 0)
rs6000_isa_flags |= OPTION_MASK_PREFIXED;
@@ -10238,6 +10257,9 @@ rs6000_conditional_register_usage (void)
for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
fixed_regs[i] = call_used_regs[i] = 1;
}
+
+ if (TARGET_TAR)
+ fixed_regs[TAR_REGNO] = 0;
}
@@ -14386,10 +14408,13 @@ print_operand (FILE *file, rtx x, int code)
if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PLTSEQ)
x = XVECEXP (x, 0, 0);
if (!REG_P (x) || (REGNO (x) != LR_REGNO
- && REGNO (x) != CTR_REGNO))
+ && REGNO (x) != CTR_REGNO
+ && REGNO (x) != TAR_REGNO))
output_operand_lossage ("invalid %%T value");
else if (REGNO (x) == LR_REGNO)
fputs ("lr", file);
+ else if (REGNO (x) == TAR_REGNO)
+ fputs ("tar", file);
else
fputs ("ctr", file);
return;
@@ -24215,6 +24240,8 @@ rs6000_debugger_regno (unsigned int regno, unsigned int format)
return 108;
if (regno == CTR_REGNO)
return 109;
+ if (regno == TAR_REGNO)
+ return 111;
if (regno == CA_REGNO)
return 101; /* XER */
/* Special handling for CR for .debug_frame: rs6000_emit_prologue has
@@ -24232,7 +24259,7 @@ rs6000_debugger_regno (unsigned int regno, unsigned int format)
/* These do not make much sense. */
if (regno == FRAME_POINTER_REGNUM)
- return 111;
+ return FIRST_PSEUDO_REGISTER;
if (regno == ARG_POINTER_REGNUM)
return 67;
if (regno == 64)
@@ -24255,6 +24282,8 @@ rs6000_debugger_regno (unsigned int regno, unsigned int format)
return 65;
if (regno == CTR_REGNO)
return 66;
+ if (regno == TAR_REGNO)
+ return 111;
if (regno == CA_REGNO)
return 76; /* XER */
if (CR_REGNO_P (regno))
@@ -24517,6 +24546,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
{ "recip-precision", OPTION_MASK_RECIP_PRECISION, false, true },
{ "save-toc-indirect", OPTION_MASK_SAVE_TOC_INDIRECT, false, true },
{ "string", 0, false, true },
+ { "tar", OPTION_MASK_TAR, false, true },
{ "update", OPTION_MASK_NO_UPDATE, true , true },
{ "vsx", OPTION_MASK_VSX, false, true },
#ifdef OPTION_MASK_64BIT
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 2e60a0395ad..ae9aff95195 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -788,7 +788,7 @@ enum data_align { align_abi, align_opt, align_both };
Another pseudo (not included in DWARF_FRAME_REGISTERS) is soft frame
pointer, which is eventually eliminated in favor of SP or FP. */
-#define FIRST_PSEUDO_REGISTER 111
+#define FIRST_PSEUDO_REGISTER 112
/* Use standard DWARF numbering for DWARF debugging information. */
#define DEBUGGER_REGNO(REGNO) rs6000_debugger_regno ((REGNO), 0)
@@ -824,8 +824,8 @@ enum data_align { align_abi, align_opt, align_both };
0, 0, 1, 1, \
/* cr0..cr7 */ \
0, 0, 0, 0, 0, 0, 0, 0, \
- /* vrsave vscr sfp */ \
- 1, 1, 1 \
+ /* vrsave vscr sfp, tar */ \
+ 1, 1, 1, 1 \
}
/* Like `CALL_USED_REGISTERS' except this macro doesn't require that
@@ -848,8 +848,8 @@ enum data_align { align_abi, align_opt, align_both };
1, 1, 1, 1, \
/* cr0..cr7 */ \
1, 1, 0, 0, 0, 1, 1, 1, \
- /* vrsave vscr sfp */ \
- 0, 0, 0 \
+ /* vrsave vscr sfp, tar */ \
+ 0, 0, 0, 1 \
}
#define TOTAL_ALTIVEC_REGS (LAST_ALTIVEC_REGNO - FIRST_ALTIVEC_REGNO + 1)
@@ -878,6 +878,7 @@ enum data_align { align_abi, align_opt, align_both };
r0 (not saved; cannot be base reg)
r31 - r13 (saved; order given to save least number)
r12 (not saved; if used for DImode or DFmode would use r13)
+ tar (not saved; tar is preferred over ctr or lr)
ctr (not saved; when we have the choice ctr is better)
lr (saved)
r1, r2, ap, ca (fixed)
@@ -920,7 +921,7 @@ enum data_align { align_abi, align_opt, align_both };
3, EARLY_R12 11, 0, \
31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \
18, 17, 16, 15, 14, 13, LATE_R12 \
- 97, 96, \
+ 111, 97, 96, \
1, MAYBE_R2_FIXED 99, 98, \
/* AltiVec registers. */ \
64, 65, \
@@ -1095,6 +1096,7 @@ enum reg_class
GEN_OR_VSX_REGS,
LINK_REGS,
CTR_REGS,
+ TAR_REGS,
LINK_OR_CTR_REGS,
SPECIAL_REGS,
SPEC_OR_GEN_REGS,
@@ -1124,6 +1126,7 @@ enum reg_class
"GEN_OR_VSX_REGS", \
"LINK_REGS", \
"CTR_REGS", \
+ "TAR_REGS", \
"LINK_OR_CTR_REGS", \
"SPECIAL_REGS", \
"SPEC_OR_GEN_REGS", \
@@ -1164,22 +1167,24 @@ enum reg_class
{ 0x00000000, 0x00000000, 0x00000000, 0x00000001 }, \
/* CTR_REGS. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000002 }, \
+ /* TAR_REGS. */ \
+ { 0x00000000, 0x00000000, 0x00000000, 0x00008000 }, \
/* LINK_OR_CTR_REGS. */ \
- { 0x00000000, 0x00000000, 0x00000000, 0x00000003 }, \
+ { 0x00000000, 0x00000000, 0x00000000, 0x00008003 }, \
/* SPECIAL_REGS. */ \
- { 0x00000000, 0x00000000, 0x00000000, 0x00001003 }, \
+ { 0x00000000, 0x00000000, 0x00000000, 0x00009003 }, \
/* SPEC_OR_GEN_REGS. */ \
- { 0xffffffff, 0x00000000, 0x00000000, 0x0000500b }, \
+ { 0xffffffff, 0x00000000, 0x00000000, 0x0000d00b }, \
/* CR0_REGS. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000010 }, \
/* CR_REGS. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000ff0 }, \
/* NON_FLOAT_REGS. */ \
- { 0xffffffff, 0x00000000, 0x00000000, 0x00004ffb }, \
+ { 0xffffffff, 0x00000000, 0x00000000, 0x0000cffb }, \
/* CA_REGS. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000004 }, \
/* ALL_REGS. */ \
- { 0xffffffff, 0xffffffff, 0xffffffff, 0x00007fff } \
+ { 0xffffffff, 0xffffffff, 0xffffffff, 0x0000ffff } \
}
/* The same information, inverted:
@@ -1201,6 +1206,7 @@ enum r6000_reg_class_enum {
RS6000_CONSTRAINT_wa, /* Any VSX register */
RS6000_CONSTRAINT_we, /* VSX register if ISA 3.0 vector. */
RS6000_CONSTRAINT_wr, /* GPR register if 64-bit */
+ RS6000_CONSTRAINT_wt, /* TAR register. */
RS6000_CONSTRAINT_wx, /* FPR register for STFIWX */
RS6000_CONSTRAINT_wA, /* BASE_REGS if 64-bit. */
RS6000_CONSTRAINT_MAX
@@ -2079,7 +2085,8 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
&rs6000_reg_names[108][0], /* vrsave */ \
&rs6000_reg_names[109][0], /* vscr */ \
\
- &rs6000_reg_names[110][0] /* sfp */ \
+ &rs6000_reg_names[110][0], /* sfp */ \
+ &rs6000_reg_names[111][0] /* tar */ \
}
/* Table of additional register names to use in user input. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index e5d3cb286cb..a42443ef008 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -51,6 +51,7 @@
(VRSAVE_REGNO 108)
(VSCR_REGNO 109)
(FRAME_POINTER_REGNUM 110)
+ (TAR_REGNO 111)
])
;;
@@ -8068,7 +8069,7 @@
[(set (match_operand:QHI 0 "nonimmediate_operand"
"=r, r, wa, m, ?Z, r,
wa, wa, wa, v, ?v, r,
- wa, r, *c*l, *h")
+ wa, r, *wt*c*l, *h")
(match_operand:QHI 1 "input_operand"
"r, m, ?Z, r, wa, i,
wa, O, wM, wB, wS, wa,
@@ -11481,7 +11482,7 @@
;; which indicates how to set cr1
(define_insn "*call_indirect_nonlocal_sysv<mode>"
- [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
+ [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "wtc,*l,X"))
(match_operand 1))
(use (match_operand:SI 2 "immediate_operand" "n,n,n"))
(clobber (reg:P LR_REGNO))]
@@ -11551,7 +11552,7 @@
(define_insn "*call_value_indirect_nonlocal_sysv<mode>"
[(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
+ (call (mem:SI (match_operand:P 1 "indirect_call_operand" "wtc,*l,X"))
(match_operand:P 2 "unspec_tls" "")))
(use (match_operand:SI 3 "immediate_operand" "n,n,n"))
(clobber (reg:P LR_REGNO))]
@@ -11668,7 +11669,7 @@
;; Operand4 is the offset of the stack location holding the current TOC pointer
(define_insn "*call_indirect_aix<mode>"
- [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
+ [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "wtc,*l,X"))
(match_operand 1))
(use (match_operand:SI 2 "immediate_operand" "n,n,n"))
(use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
@@ -11687,7 +11688,7 @@
(define_insn "*call_value_indirect_aix<mode>"
[(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
+ (call (mem:SI (match_operand:P 1 "indirect_call_operand" "wtc,*l,X"))
(match_operand:P 2 "unspec_tls" "")))
(use (match_operand:SI 3 "immediate_operand" "n,n,n"))
(use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
@@ -11711,7 +11712,7 @@
;; Operand3 is the offset of the stack location holding the current TOC pointer
(define_insn "*call_indirect_elfv2<mode>"
- [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
+ [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "wtc,*l,X"))
(match_operand 1))
(use (match_operand:SI 2 "immediate_operand" "n,n,n"))
(set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
@@ -11728,7 +11729,7 @@
(const_string "8")))])
(define_insn "*call_indirect_pcrel<mode>"
- [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
+ [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "wtc,*l,X"))
(match_operand 1))
(use (match_operand:SI 2 "immediate_operand" "n,n,n"))
(clobber (reg:P LR_REGNO))]
@@ -11745,7 +11746,7 @@
(define_insn "*call_value_indirect_elfv2<mode>"
[(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
+ (call (mem:SI (match_operand:P 1 "indirect_call_operand" "wtc,*l,X"))
(match_operand:P 2 "unspec_tls" "")))
(use (match_operand:SI 3 "immediate_operand" "n,n,n"))
(set (reg:P TOC_REGNUM)
@@ -11765,7 +11766,7 @@
(define_insn "*call_value_indirect_pcrel<mode>"
[(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
+ (call (mem:SI (match_operand:P 1 "indirect_call_operand" "wtc,*l,X"))
(match_operand:P 2 "unspec_tls" "")))
(use (match_operand:SI 3 "immediate_operand" "n,n,n"))
(clobber (reg:P LR_REGNO))]
@@ -11909,7 +11910,7 @@
(set_attr "length" "4,8")])
(define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
- [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
+ [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "wtc,*l,X"))
(match_operand 1))
(use (match_operand:SI 2 "immediate_operand" "n,n,n"))
(simple_return)]
@@ -11958,7 +11959,7 @@
(define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
[(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
+ (call (mem:SI (match_operand:P 1 "indirect_call_operand" "wtc,*l,X"))
(match_operand 2)))
(use (match_operand:SI 3 "immediate_operand" "n,n,n"))
(simple_return)]
@@ -13478,14 +13479,14 @@
(define_insn "*indirect_jump<mode>"
[(set (pc)
- (match_operand:P 0 "register_operand" "c,*l"))]
+ (match_operand:P 0 "register_operand" "wt,c,*l"))]
"rs6000_speculate_indirect_jumps"
"b%T0"
[(set_attr "type" "jmpreg")])
(define_insn "@indirect_jump<mode>_nospec"
- [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
- (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
+ [(set (pc) (match_operand:P 0 "register_operand" "wt,c,*l"))
+ (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y,y"))]
"!rs6000_speculate_indirect_jumps"
"crset %E1\;beq%T0- %1\;b $"
[(set_attr "type" "jmpreg")
@@ -13591,7 +13592,7 @@
(define_insn "@tablejump<mode>_insn_normal"
[(set (pc)
- (match_operand:P 0 "register_operand" "c,*l"))
+ (match_operand:P 0 "register_operand" "wt,c,*l"))
(use (label_ref (match_operand 1)))]
"rs6000_speculate_indirect_jumps"
"b%T0"
@@ -13599,9 +13600,9 @@
(define_insn "@tablejump<mode>_insn_nospec"
[(set (pc)
- (match_operand:P 0 "register_operand" "c,*l"))
+ (match_operand:P 0 "register_operand" "wt,c,*l"))
(use (label_ref (match_operand 1)))
- (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
+ (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y,y"))]
"!rs6000_speculate_indirect_jumps"
"crset %E2\;beq%T0- %2\;b $"
[(set_attr "type" "jmpreg")
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 70fd7080bc5..7f7a283bc99 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -630,6 +630,10 @@ mieee128-constant
Target Var(TARGET_IEEE128_CONSTANT) Init(1) Save
Generate (do not generate) code that uses the LXVKQ instruction.
+mtar
+Target Undocumented Mask(TAR) Var(rs6000_isa_flags)
+Allow (do not allow) use the TAR register.
+
; Documented parameters
-param=rs6000-vect-unroll-limit=
diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c b/gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c
index eb379a0f67d..7c1031d1b39 100644
--- a/gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c
@@ -1,8 +1,8 @@
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } } */
/* { dg-options "-O2 --param case-values-threshold=2" } */
-/* { dg-final { scan-assembler "mtctr" } } */
-/* { dg-final { scan-assembler "bctr" } } */
+/* { dg-final { scan-assembler "mt\(ctr\|tar\)" } } */
+/* { dg-final { scan-assembler "b\(ctr\|tar\)" } } */
/* Force using a dispatch table even though by default we would generate
ifs. */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr51513.c b/gcc/testsuite/gcc.target/powerpc/pr51513.c
index 1c72a75502a..43c06da8f32 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr51513.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr51513.c
@@ -1,8 +1,8 @@
/* { dg-do compile { target { powerpc*-*-linux* } } } */
/* { dg-options "-O2 -fjump-tables --param case-values-threshold=1" } */
/* Verify we created a jump table. */
-/* { dg-final { scan-assembler-times "mtctr " 1 } } */
-/* { dg-final { scan-assembler-times "bctr" 1 } } */
+/* { dg-final { scan-assembler-times "mt\(ctr\|tar\) " 1 } } */
+/* { dg-final { scan-assembler-times "b\(ctr\|tar\)" 1 } } */
/* Verify we eliminated the range check. */
/* { dg-final { scan-assembler-not "cmpldi" } } */
/* { dg-final { scan-assembler-not "cmplwi" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-2.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-2.c
index d6fc6a3e0b7..791537921c8 100644
--- a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-2.c
@@ -28,5 +28,5 @@ int foo (int x)
}
/* { dg-final { scan-assembler "crset" } } */
-/* { dg-final { scan-assembler "beqctr-" } } */
+/* { dg-final { scan-assembler "beq\(ctr\|tar\)-" } } */
/* { dg-final { scan-assembler {b \$} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c
index 87881fb18fc..f61a4dbfad8 100644
--- a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c
@@ -47,5 +47,5 @@ int foo (int x)
}
/* { dg-final { scan-assembler "crset" } } */
-/* { dg-final { scan-assembler "beqctr-" } } */
+/* { dg-final { scan-assembler "beq\(ctr\|tar\)-" } } */
/* { dg-final { scan-assembler {b \$} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/tar-register.c b/gcc/testsuite/gcc.target/powerpc/tar-register.c
new file mode 100644
index 00000000000..66e8e9ff6ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/tar-register.c
@@ -0,0 +1,34 @@
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+/* Test to see if both the CTR and TAR registers are used on power10. */
+
+long foo (long value, long n, int cond)
+{
+ long i;
+ long sum = 0;
+ void *label = ((cond > 0) ? &&label1 : &&label2);
+
+ for (i = 0; i < n; i++)
+ {
+ if (value)
+ goto *label;
+ continue;
+
+ label1:
+ sum += value;
+ continue;
+
+ label2:
+ sum -= value;
+ continue;
+ }
+
+ return sum;
+}
+
+
+/* { dg-final { scan-assembler {\mmtctr\M} } } */
+/* { dg-final { scan-assembler {\mmttar\M} } } */
+/* { dg-final { scan-assembler-not {\mbctr\M} } } */
+/* { dg-final { scan-assembler {\mbtar\M} } } */
More information about the Gcc-cvs
mailing list