diff options
author | Michael Meissner <meissner@linux.vnet.ibm.com> | 2015-11-25 22:49:41 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 2015-11-25 22:49:41 +0000 |
commit | d5906efcaa2b75bc7991909cf56f934d141ecbdb (patch) | |
tree | 7526c55451b8bf3ed828f529ef373b6378be87b8 /gcc/config | |
parent | 22bea0be95010c6efc39649d06e0f15c90ca38c4 (diff) | |
download | gcc-d5906efcaa2b75bc7991909cf56f934d141ecbdb.tar.gz |
<patch #10>
[gcc]
2015-11-25 Michael Meissner <meissner@linux.vnet.ibm.com>
<patch #10>
* config/rs6000/constraints.md (wb constraint): New constraint for
ISA 3.0 d-form scalar addressing.
* config/rs6000/rs6000.c (mode_supports_vmx_dform): Add support
for ISA 3.0 D-form addressing to load SFmode/DFmode scalars into
Altivec registers. Add wb constraint for Altivec registers with
D-form addressing. If we have ISA 3.0 d-form support, undo
secondary reload support for using FPR registers if we want to do
D-form addressing.
(rs6000_debug_reg_global): Likewise.
(rs6000_setup_reg_addr_masks): Likewise.
(rs6000_init_hard_regno_mode_ok): Likewise.
(rs6000_secondary_reload): Likewise.
(rs6000_preferred_reload_class): Likewise.
(rs6000_secondary_reload_class): Likewise.
* config/rs6000/rs6000.h (enum r6000_reg_class_enum): Add wb
constraint.
* config/rs6000/rs6000.md (f32_lr2 mode attribute): Add support
for ISA 3.0 SFmode/DFmode d-form addressing to Altivec registers.
(f32_lm2): Likewise.
(f32_li2): Likewise.
(f32_sr2): Likewise.
(f32_sm2): Likewise.
(f32_si2): Likewise.
(f64_p9): Likewise.
(extendsfdf2_fpr): Likewise.
(mov<mode>_hardfloat): Likewise.
(mov<mode>_hardfloat32): Likewise.
(mov<mode>_hardfloat64): Likewise.
* doc/md.texi (RS/6000 constraints): Document wb constraint.
Fixup we constraint documentation.
[gcc/testsuite]
2015-11-25 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/dform-1.c: New test.
* gcc.target/powerpc/dform-2.c: Likewise.
From-SVN: r230913
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/rs6000/constraints.md | 3 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 42 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 1 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 63 |
4 files changed, 78 insertions, 31 deletions
diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md index e4129453736..1e7f27b7d6f 100644 --- a/gcc/config/rs6000/constraints.md +++ b/gcc/config/rs6000/constraints.md @@ -56,7 +56,8 @@ (define_register_constraint "wa" "rs6000_constraints[RS6000_CONSTRAINT_wa]" "Any VSX register if the -mvsx option was used or NO_REGS.") -;; wb is not currently used +(define_register_constraint "wb" "rs6000_constraints[RS6000_CONSTRAINT_wb]" + "Altivec register if the -mpower9-dform option was used or NO_REGS.") ;; NOTE: For compatibility, "wc" is reserved to represent individual CR bits. ;; It is currently used for that purpose in LLVM. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 31e9301b758..ba00b61377a 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -409,6 +409,13 @@ mode_supports_pre_modify_p (machine_mode mode) != 0); } +/* Return true if we have D-form addressing in altivec registers. */ +static inline bool +mode_supports_vmx_dform (machine_mode mode) +{ + return ((reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_OFFSET) != 0); +} + /* Target cpu costs. */ @@ -2263,7 +2270,9 @@ rs6000_debug_reg_global (void) "f reg_class = %s\n" "v reg_class = %s\n" "wa reg_class = %s\n" + "wb reg_class = %s\n" "wd reg_class = %s\n" + "we reg_class = %s\n" "wf reg_class = %s\n" "wg reg_class = %s\n" "wh reg_class = %s\n" @@ -2288,7 +2297,9 @@ rs6000_debug_reg_global (void) reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wb]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_we]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wg]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wh]], @@ -2669,9 +2680,15 @@ rs6000_setup_reg_addr_masks (void) } /* GPR and FPR registers can do REG+OFFSET addressing, except - possibly for SDmode. */ + possibly for SDmode. ISA 3.0 (i.e. power9) adds D-form + addressing for scalars to altivec registers. */ if ((addr_mask != 0) && !indexed_only_p - && (rc == RELOAD_REG_GPR || rc == RELOAD_REG_FPR)) + && msize <= 8 + && (rc == RELOAD_REG_GPR + || rc == RELOAD_REG_FPR + || (rc == RELOAD_REG_VMX + && TARGET_P9_DFORM + && (m2 == DFmode || m2 == SFmode)))) addr_mask |= RELOAD_REG_OFFSET; /* VMX registers can do (REG & -16) and ((REG+REG) & -16) @@ -2995,6 +3012,10 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) rs6000_constraints[RS6000_CONSTRAINT_wp] = VSX_REGS; /* TFmode */ } + /* Support for new D-form instructions. */ + if (TARGET_P9_DFORM) + rs6000_constraints[RS6000_CONSTRAINT_wb] = ALTIVEC_REGS; + /* Support for new direct moves. */ if (TARGET_DIRECT_MOVE_128) rs6000_constraints[RS6000_CONSTRAINT_we] = VSX_REGS; @@ -18260,8 +18281,10 @@ rs6000_secondary_reload (bool in_p, /* If this is a scalar floating point value and we want to load it into the traditional Altivec registers, do it via a move via a traditional floating - point register. Also make sure that non-zero constants use a FPR. */ + point register, unless we have D-form addressing. Also make sure that + non-zero constants use a FPR. */ if (!done_p && reg_addr[mode].scalar_in_vmx_p + && !mode_supports_vmx_dform (mode) && (rclass == VSX_REGS || rclass == ALTIVEC_REGS) && (memory_p || (GET_CODE (x) == CONST_DOUBLE))) { @@ -18825,10 +18848,14 @@ rs6000_preferred_reload_class (rtx x, enum reg_class rclass) return NO_REGS; } - /* If this is a scalar floating point value, prefer the traditional - floating point registers so that we can use D-form (register+offset) - addressing. */ - if (GET_MODE_SIZE (mode) < 16) + /* D-form addressing can easily reload the value. */ + if (mode_supports_vmx_dform (mode)) + return rclass; + + /* If this is a scalar floating point value and we don't have D-form + addressing, prefer the traditional floating point registers so that we + can use D-form (register+offset) addressing. */ + if (GET_MODE_SIZE (mode) < 16 && rclass == VSX_REGS) return FLOAT_REGS; /* Prefer the Altivec registers if Altivec is handling the vector @@ -18977,6 +19004,7 @@ rs6000_secondary_reload_class (enum reg_class rclass, machine_mode mode, instead of reloading the secondary memory address for Altivec moves. */ if (TARGET_VSX && GET_MODE_SIZE (mode) < 16 + && !mode_supports_vmx_dform (mode) && (((rclass == GENERAL_REGS || rclass == BASE_REGS) && (regno >= 0 && ALTIVEC_REGNO_P (regno))) || ((rclass == VSX_REGS || rclass == ALTIVEC_REGS) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 8c606ab0aea..dafe3acf912 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1523,6 +1523,7 @@ enum r6000_reg_class_enum { RS6000_CONSTRAINT_f, /* fpr registers for single values */ RS6000_CONSTRAINT_v, /* Altivec registers */ RS6000_CONSTRAINT_wa, /* Any VSX register */ + RS6000_CONSTRAINT_wb, /* Altivec register if ISA 3.0 vector. */ RS6000_CONSTRAINT_wd, /* VSX register for V2DF */ RS6000_CONSTRAINT_we, /* VSX register if ISA 3.0 vector. */ RS6000_CONSTRAINT_wf, /* VSX register for V4SF */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 7623c9f6819..a500d67efa9 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -429,16 +429,22 @@ (DD "REAL_VALUE_TO_TARGET_DECIMAL64")]) ; Definitions for load to 32-bit fpr register -(define_mode_attr f32_lr [(SF "f") (SD "wz")]) -(define_mode_attr f32_lm [(SF "m") (SD "Z")]) -(define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")]) -(define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")]) +(define_mode_attr f32_lr [(SF "f") (SD "wz")]) +(define_mode_attr f32_lr2 [(SF "wb") (SD "wn")]) +(define_mode_attr f32_lm [(SF "m") (SD "Z")]) +(define_mode_attr f32_lm2 [(SF "o") (SD "wn")]) +(define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")]) +(define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")]) +(define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")]) ; Definitions for store from 32-bit fpr register -(define_mode_attr f32_sr [(SF "f") (SD "wx")]) -(define_mode_attr f32_sm [(SF "m") (SD "Z")]) -(define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")]) -(define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")]) +(define_mode_attr f32_sr [(SF "f") (SD "wx")]) +(define_mode_attr f32_sr2 [(SF "wb") (SD "wn")]) +(define_mode_attr f32_sm [(SF "m") (SD "Z")]) +(define_mode_attr f32_sm2 [(SF "o") (SD "wn")]) +(define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")]) +(define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")]) +(define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")]) ; Definitions for 32-bit fpr direct move ; At present, the decimal modes are not allowed in the traditional altivec @@ -460,6 +466,9 @@ ; Definitions for 64-bit use of altivec registers (define_mode_attr f64_av [(DF "wv") (DD "wn")]) +; Definitions for 64-bit access to ISA 3.0 (power9) vector +(define_mode_attr f64_p9 [(DF "wb") (DD "wn")]) + ; These modes do not fit in integer registers in 32-bit mode. ; but on e500v2, the gpr are 64 bit registers (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD]) @@ -4468,8 +4477,8 @@ "") (define_insn_and_split "*extendsfdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu") - (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb") + (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "@ # @@ -4477,14 +4486,15 @@ lfs%U1%X1 %0,%1 # xscpsgndp %x0,%x1,%x1 - lxsspx %x0,%y1" + lxsspx %x0,%y1 + lxssp %0,%1" "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])" [(const_int 0)] { emit_note (NOTE_INSN_DELETED); DONE; } - [(set_attr "type" "fp,fp,fpload,fp,fp,fpload")]) + [(set_attr "type" "fp,fp,fpload,fp,fp,fpload,fpload")]) (define_expand "truncdfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") @@ -6469,8 +6479,8 @@ }") (define_insn "mov<mode>_hardfloat" - [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_sm>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h") - (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,j,<f32_lm>,<f32_sr>,Z,<f32_av>,r,<f32_dm>,r,h,0"))] + [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_lr2>,<f32_sm>,<f32_sm2>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h") + (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,j,<f32_lm>,<f32_lm2>,<f32_sr>,<f32_sr2>,Z,<f32_av>,r,<f32_dm>,r,h,0"))] "(gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode)) && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)" @@ -6483,7 +6493,9 @@ xxlxor %x0,%x0,%x0 li %0,0 <f32_li> + <f32_li2> <f32_si> + <f32_si2> <f32_lv> <f32_sv> mtvsrwz %x0,%1 @@ -6491,7 +6503,7 @@ mt%0 %1 mf%1 %0 nop" - [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*") + [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*") (set_attr "length" "4")]) (define_insn "*mov<mode>_softfloat" @@ -6600,14 +6612,15 @@ ;; into a floating point register when it is needed for a floating point ;; operation. Prefer traditional floating point registers over VSX registers, ;; since the D-form version of the memory instructions does not need a GPR for -;; reloading. +;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec +;; registers. ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory, ;; except for 0.0 which can be created on VSX with an xor instruction. (define_insn "*mov<mode>_hardfloat32" - [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r") - (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r"))] + [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,o,<f64_vsx>,<f64_vsx>,!r,Y,r,!r") + (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,o,<f64_p9>,<f64_vsx>,j,j,r,Y,r"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode))" @@ -6617,14 +6630,16 @@ fmr %0,%1 lxsd%U1x %x0,%y1 stxsd%U0x %x1,%y0 + lxsd %0,%1 + stxsd %1,%0 xxlor %x0,%x1,%x1 xxlxor %x0,%x0,%x0 # # # #" - [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,two,store,load,two") - (set_attr "length" "4,4,4,4,4,4,4,8,8,8,8")]) + [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,two,store,load,two") + (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")]) (define_insn "*mov<mode>_softfloat32" [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r") @@ -6642,8 +6657,8 @@ ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*mov<mode>_hardfloat64" - [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>") - (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))] + [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,o,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>") + (match_operand:FMOVE64 1 "input_operand" "d,m,d,o,<f64_p9>,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))] "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode))" @@ -6651,6 +6666,8 @@ stfd%U0%X0 %1,%0 lfd%U1%X1 %0,%1 fmr %0,%1 + lxsd %0,%1 + stxsd %1,%0 lxsd%U1x %x0,%y1 stxsd%U0x %x1,%y0 xxlor %x0,%x1,%x1 @@ -6666,7 +6683,7 @@ mffgpr %0,%1 mfvsrd %0,%x1 mtvsrd %x0,%1" - [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr") + [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr") (set_attr "length" "4")]) (define_insn "*mov<mode>_softfloat64" |