From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1005) id 6D6D83861811; Wed, 14 Feb 2024 23:13:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6D6D83861811 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1707952385; bh=1t2X6Oi23wh3jQ83NMedOKbR0DDDOaVFtE7qujKSbCo=; h=From:To:Subject:Date:From; b=izlaBLXAcepbzlHi7TqMoPatiWdnC6dzSQaeFkql94p467QV7TuAo6SlGRDZ1pyMJ c7t8jIb96R4/Kw92hMaK/1zTeyX83oGRU8Bxm1tkKnueQyBMBljXy3CsVSdE8h5JLz +hcGoAzeX+20D3QlY7lW12+gU8bsOj1DiGc5QWWs= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Michael Meissner To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/meissner/heads/work154-dmf)] Add paddis support. X-Act-Checkin: gcc X-Git-Author: Michael Meissner X-Git-Refname: refs/users/meissner/heads/work154-dmf X-Git-Oldrev: d6b1f599ffd136e199df71e83e6912668c439a1a X-Git-Newrev: 94411c6d43a13016f172c8070a69a4159ad84e46 Message-Id: <20240214231305.6D6D83861811@sourceware.org> Date: Wed, 14 Feb 2024 23:13:05 +0000 (GMT) List-Id: https://gcc.gnu.org/g:94411c6d43a13016f172c8070a69a4159ad84e46 commit 94411c6d43a13016f172c8070a69a4159ad84e46 Author: Michael Meissner Date: Tue Jan 23 00:20:41 2024 -0500 Add paddis support. 2024-01-23 Michael Meissner gcc/ * config/rs6000/constraints.md (eU): New constraint. (eV): Likewise. * config/rs6000/predicates.md (paddis_operand): New predicate. (paddis_paddi_operand): Likewise. (add_operand): Add paddis support. * config/rs6000/rs6000-cpus.def (ISA_FUTURE_MASKS): Add -mpaddis support. (POWERPC_MASKS): Likewise. * config/rs6000/rs6000.cc (num_insns_constant_gpr): Add -mpaddis support. (num_insns_constant_multi): Likewise. (print_operand): Add %B for paddis support. (rs6000_opt_masks): Add -mpaddis. & config/rs6000/rs6000.h (SIGNED_INTEGER_32BIT_P): New macro. * config/rs6000/rs6000.md (isa attribute): Add -mpaddis support. (enabled attribute); Likewise. (add3): Likewise. (adddi3 splitter): New splitter for paddis. (movdi_internal64): Add -mpaddis support. (movdi splitter): New splitter for -mpaddis. * config/rs6000/rs6000.opt (-mpaddis): New switch. Diff: --- gcc/config/rs6000/constraints.md | 10 +++++ gcc/config/rs6000/predicates.md | 52 +++++++++++++++++++++- gcc/config/rs6000/rs6000.cc | 40 +++++++++++++++++ gcc/config/rs6000/rs6000.h | 1 + gcc/config/rs6000/rs6000.md | 96 ++++++++++++++++++++++++++++++++++------ gcc/config/rs6000/rs6000.opt | 4 ++ 6 files changed, 189 insertions(+), 14 deletions(-) diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md index 614e431c085d..c438f102b0ca 100644 --- a/gcc/config/rs6000/constraints.md +++ b/gcc/config/rs6000/constraints.md @@ -222,6 +222,16 @@ "An IEEE 128-bit constant that can be loaded into VSX registers." (match_operand 0 "easy_vector_constant_ieee128")) +(define_constraint "eU" + "@internal integer constant that can be loaded with paddis" + (and (match_code "const_int") + (match_operand 0 "paddis_operand"))) + +(define_constraint "eV" + "@internal integer constant that can be loaded with paddis + paddi" + (and (match_code "const_int") + (match_operand 0 "paddis_paddi_operand"))) + ;; Floating-point constraints. These two are defined so that insn ;; length attributes can be calculated exactly. diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 3040dcd50a33..7ec02448c48d 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -369,6 +369,53 @@ return SIGNED_INTEGER_34BIT_P (INTVAL (op)); }) +;; Return 1 if op is a 64-bit constant that uses the paddis instruction +(define_predicate "paddis_operand" + (match_code "const_int") +{ + if (!TARGET_PADDIS && TARGET_POWERPC64) + return 0; + + /* If addi, addis, or paddi can handle the number, don't return true. */ + HOST_WIDE_INT value = INTVAL (op); + if (SIGNED_INTEGER_34BIT_P (value)) + return false; + + /* If the number is too large for padds, return false. */ + if (!SIGNED_INTEGER_32BIT_P (value >> 32)) + return false; + + /* If the bottom 32-bits are non-zero, paddis can't handle it. */ + if ((value & HOST_WIDE_INT_C(0xffffffff)) != 0) + return false; + + return true; +}) + +;; Return 1 if op is a 64-bit constant that needs the paddis instruction and an +;; addi/addis/paddi instruction combination. +(define_predicate "paddis_paddi_operand" + (match_code "const_int") +{ + if (!TARGET_PADDIS && TARGET_POWERPC64) + return 0; + + /* If addi, addis, or paddi can handle the number, don't return true. */ + HOST_WIDE_INT value = INTVAL (op); + if (SIGNED_INTEGER_34BIT_P (value)) + return false; + + /* If the number is too large for padds, return false. */ + if (!SIGNED_INTEGER_32BIT_P (value >> 32)) + return false; + + /* If the bottom 32-bits are zero, we can use paddis alone to handle it. */ + if ((value & HOST_WIDE_INT_C(0xffffffff)) == 0) + return false; + + return true; +}) + ;; Return 1 if op is a register that is not special. ;; Disallow (SUBREG:SF (REG:SI)) and (SUBREG:SI (REG:SF)) on VSX systems where ;; you need to be careful in moving a SFmode to SImode and vice versa due to @@ -1050,7 +1097,10 @@ (if_then_else (match_code "const_int") (match_test "satisfies_constraint_I (op) || satisfies_constraint_L (op) - || satisfies_constraint_eI (op)") + || satisfies_constraint_eI (op) + || satisfies_constraint_eU (op) + || satisfies_constraint_eV (op)") + (match_operand 0 "gpc_reg_operand"))) ;; Return 1 if the operand is either a non-special register, or 0, or -1. diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 627410c1fa32..6bb0aa52fa2e 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -4410,6 +4410,16 @@ rs6000_option_override_internal (bool global_init_p) rs6000_isa_flags &= ~OPTION_MASK_PCREL; } + + /* -mpaddis requires -mcpu=future. */ + if (TARGET_PADDIS && !TARGET_FUTURE) + { + if (OPTION_SET_P (TARGET_PADDIS)) + error ("%qs requires %qs", "-mpaddis", "-mcpu=future"); + + TARGET_PADDIS = 0; + } + /* Print the options after updating the defaults. */ if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET) rs6000_print_isa_options (stderr, 0, "after defaults", rs6000_isa_flags); @@ -6239,6 +6249,17 @@ num_insns_constant_gpr (HOST_WIDE_INT value) else if (TARGET_PREFIXED && SIGNED_INTEGER_34BIT_P (value)) return 1; + /* PADDIS support. */ + else if (TARGET_PADDIS && TARGET_POWERPC64 + && !IN_RANGE (value >> 32, -1, 0) + && (SIGNED_INTEGER_32BIT_P (value >> 32))) + { + fprintf (stderr, "=== 0x%lx ===\n", (long)value); + return ((value & HOST_WIDE_INT_C (0xffffffff)) == 0 + ? 1 + : 2); + } + else if (TARGET_POWERPC64) { int num_insns = 0; @@ -6259,6 +6280,14 @@ num_insns_constant_multi (HOST_WIDE_INT value, machine_mode mode) { int nregs = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; int total = 0; + if (nregs == 1 + && TARGET_PADDIS && TARGET_POWERPC64 + && !IN_RANGE (value >> 32, -1, 0) + && SIGNED_INTEGER_32BIT_P (value >> 32)) + return ((value & HOST_WIDE_INT_C (0xffffffff)) == 0 + ? 1 + : 2); + while (nregs-- > 0) { HOST_WIDE_INT low = sext_hwi (value, BITS_PER_WORD); @@ -14332,6 +14361,14 @@ print_operand (FILE *file, rtx x, int code) fprintf (file, "%d", (REGNO (x) - FIRST_FPR_REGNO) / 4); return; + case 'B': + /* Upper 32-bits of a constant. */ + if (!CONST_INT_P (x)) + output_operand_lossage ("Not a constant."); + + fprintf (file, "%" HOST_LONG_FORMAT "d", INTVAL (x) >> 32); + return; + case 'D': /* Like 'J' but get to the GT bit only. */ if (!REG_P (x) || !CR_REGNO_P (REGNO (x))) @@ -24858,6 +24895,9 @@ static struct rs6000_opt_var const rs6000_opt_vars[] = { "speculate-indirect-jumps", offsetof (struct gcc_options, x_rs6000_speculate_indirect_jumps), offsetof (struct cl_target_option, x_rs6000_speculate_indirect_jumps), }, + { "paddis", + offsetof (struct gcc_options, x_TARGET_PADDIS), + offsetof (struct cl_target_option, x_TARGET_PADDIS), }, }; /* Inner function to handle attribute((target("..."))) and #pragma GCC target diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 9711777b5cdc..572c07c7f4b0 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2491,6 +2491,7 @@ typedef struct GTY(()) machine_function (HOST_WIDE_INT_1 << ((N)-1)) - 1) #define SIGNED_INTEGER_16BIT_P(VALUE) SIGNED_INTEGER_NBIT_P (VALUE, 16) +#define SIGNED_INTEGER_32BIT_P(VALUE) SIGNED_INTEGER_NBIT_P (VALUE, 32) #define SIGNED_INTEGER_34BIT_P(VALUE) SIGNED_INTEGER_NBIT_P (VALUE, 34) /* Like SIGNED_INTEGER_16BIT_P and SIGNED_INTEGER_34BIT_P, but with an extra diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index a2d31e982b0b..dfdef62469a1 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -357,7 +357,7 @@ (const (symbol_ref "(enum attr_cpu) rs6000_tune"))) ;; The ISA we implement. -(define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10,lxvp,stxvp,dm,not_dm" +(define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10,lxvp,stxvp,dm,not_dm,paddis" (const_string "any")) ;; Is this alternative enabled for the current CPU/ISA/etc.? @@ -421,6 +421,11 @@ (and (eq_attr "isa" "not_dm") (match_test "!TARGET_DENSE_MATH")) (const_int 1) + + (and (eq_attr "isa" "paddis") + (match_test "TARGET_PADDIS")) + (const_int 1) + ] (const_int 0))) ;; If this instruction is microcoded on the CELL processor @@ -1826,17 +1831,42 @@ }) (define_insn "*add3" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r") - (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b") - (match_operand:GPR 2 "add_operand" "r,I,L,eI")))] + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r,r,b") + (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b,b,b") + (match_operand:GPR 2 "add_operand" "r,I,L,eI,eU,eV")))] "" "@ add %0,%1,%2 addi %0,%1,%2 addis %0,%1,%v2 - addi %0,%1,%2" + addi %0,%1,%2 + paddis %0,%1,%B2 + #" [(set_attr "type" "add") - (set_attr "isa" "*,*,*,p10")]) + (set_attr "isa" "*,*,*,p10,paddis,paddis") + (set_attr "length" "*,*,*,*,12,24") + (set_attr "prefixed" "*,*,*,*,yes,yes") + (set_attr "maybe_prefixed" "*,*,*,*,no,no")]) + +(define_split + [(set (match_operand:DI 0 "gpc_reg_operand") + (plus:DI (match_operand:DI 1 "gpc_reg_operand") + (match_operand:DI 2 "paddis_paddi_operand")))] + "TARGET_PADDIS && TARGET_POWERPC64" + [(set (match_dup 3) + (plus:DI (match_dup 1) + (match_dup 4))) + (set (match_dup 0) + (plus:DI (match_dup 3) + (match_dup 5)))] +{ + HOST_WIDE_INT value = INTVAL (operands[2]); + operands[3] = (can_create_pseudo_p () + ? gen_reg_rtx (DImode) + : operands[0]); + operands[4] = GEN_INT (value & ~HOST_WIDE_INT_C (0xffffffff)); + operands[5] = GEN_INT (value & HOST_WIDE_INT_C (0xffffffff)); +}) (define_insn "*addsi3_high" [(set (match_operand:SI 0 "gpc_reg_operand" "=b") @@ -9851,7 +9881,7 @@ DONE; }) -;; GPR store GPR load GPR move +;; GPR store GPR load GPR move GPR paddis GPR paddis+paddi ;; GPR li GPR lis GPR pli GPR # ;; FPR store FPR load FPR move ;; AVX store AVX store AVX load AVX load VSX move @@ -9861,7 +9891,7 @@ ;; VSX->GPR GPR->VSX (define_insn "*movdi_internal64" [(set (match_operand:DI 0 "nonimmediate_operand" - "=YZ, r, r, + "=YZ, r, r, r, b, r, r, r, r, m, ^d, ^d, wY, Z, $v, $v, ^wa, @@ -9870,7 +9900,7 @@ r, *h, *h, ?r, ?wa") (match_operand:DI 1 "input_operand" - "r, YZ, r, + "r, YZ, r, eU, eV, I, L, eI, nF, ^d, m, ^d, ^v, $v, wY, Z, ^wa, @@ -9885,6 +9915,8 @@ std%U0%X0 %1,%0 ld%U1%X1 %0,%1 mr %0,%1 + paddis %0,0,%B1 + # li %0,%1 lis %0,%v1 li %0,%1 @@ -9910,7 +9942,7 @@ mfvsrd %0,%x1 mtvsrd %x0,%1" [(set_attr "type" - "store, load, *, + "store, load, *, *, *, *, *, *, *, fpstore, fpload, fpsimple, fpstore, fpstore, fpload, fpload, veclogical, @@ -9920,7 +9952,7 @@ mfvsr, mtvsr") (set_attr "size" "64") (set_attr "length" - "*, *, *, + "*, *, *, 12, 24, *, *, *, 20, *, *, *, *, *, *, *, *, @@ -9929,14 +9961,32 @@ *, *, *, *, *") (set_attr "isa" - "*, *, *, + "*, *, *, paddis, paddis, *, *, p10, *, *, *, *, p9v, p7v, p9v, p7v, *, p9v, p9v, p7v, *, *, p7v, p7v, *, *, *, - p8v, p8v")]) + p8v, p8v") + (set_attr "prefixed" + "*, *, *, yes, yes, + *, *, *, *, + *, *, *, + *, *, *, *, *, + *, *, *, *, *, + *, *, + *, *, *, + *, *") + (set_attr "maybe_prefixed" + "*, *, *, no, no, + *, *, *, *, + *, *, *, + *, *, *, *, *, + *, *, *, *, *, + *, *, + *, *, *, + *, *")]) ; Some DImode loads are best done as a load of -1 followed by a mask ; instruction. @@ -9954,6 +10004,26 @@ (match_dup 1)))] "") +;; Split a constant that can be generated by a paddis and paddi into 2 +;; instructions. +(define_split + [(set (match_operand:DI 0 "int_reg_operand") + (match_operand:DI 1 "paddis_paddi_operand"))] + "TARGET_PADDIS && TARGET_POWERPC64" + [(set (match_dup 2) + (match_dup 3)) + (set (match_dup 0) + (plus:DI (match_dup 2) + (match_dup 4)))] +{ + HOST_WIDE_INT value = INTVAL (operands[1]); + operands[2] = (can_create_pseudo_p () + ? gen_reg_rtx (DImode) + : operands[0]); + operands[3] = GEN_INT (value & ~HOST_WIDE_INT_C (0xffffffff)); + operands[4] = GEN_INT (value & HOST_WIDE_INT_C (0xffffffff)); +}) + ;; Split a load of a large constant into the appropriate five-instruction ;; sequence. Handle anything in a constant number of insns. ;; When non-easy constants can go in the TOC, this should use diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index 70913d88d39e..382e95465b1a 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -605,6 +605,10 @@ mstore-vector-pair Target Undocumented Mask(STORE_VECTOR_PAIR) Var(rs6000_isa_flags) Generate (do not generate) store vector pair instructions. +mpaddis +Target Undocumented Var(TARGET_PADDIS) Save +Generate (do not generate) the paddis instruction. + mrelative-jumptables Target Undocumented Var(rs6000_relative_jumptables) Init(1) Save