From ad69178ca9b691e39308062bc46a801806ea1030 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 8 Aug 2016 18:35:16 +0930 Subject: [PATCH] [RS6000] PR72802 part 1, fix constraints for lxssp/stxssp We can't use "o" constraint for lsxxp/stxssp since those insns have a DS-form offset field, ie. the bottom two bits of the offset must be 0. So use "wY" instead, but that leads to finding another problem. mem_operand_gpr is only suitable for gpr loads/stores since it does not enforce multiple-of-4 offsets when -m32. So "wY" can't use mem_operand_gpr, and the vsx tests in mem_operand_gpr are bogus. I've deleted offsettable_mem_14bit_operand because it wasn't used anywhere but in the wY constraint. Note also that the new wY constraint doesn't use memory_operand because that is redundant in a constraint, having already been tested in the predicate. PR target/72802 * config/rs6000/rs6000.c (mem_operand_gpr): Remove vsx dform test. (mem_operand_ds_form): New predicate. * config/rs6000/rs6000-protos.h (mem_operand_ds_form): Declare. * config/rs6000/constraints.md (wY): Use mem_operand_df_form. * config/rs6000/predicates.md (offsettable_mem_14bit_operand): Delete. * config/rs6000/rs6000.md (f32_lm2, f32_sm2): Use wY for SF. (extendsfdf2_fpr): Replace o constraint with wY. From-SVN: r239233 --- gcc/ChangeLog | 11 +++++++++++ gcc/config/rs6000/constraints.md | 8 ++++++-- gcc/config/rs6000/predicates.md | 9 --------- gcc/config/rs6000/rs6000-protos.h | 1 + gcc/config/rs6000/rs6000.c | 30 ++++++++++++++++++++++++++++-- gcc/config/rs6000/rs6000.md | 6 +++--- 6 files changed, 49 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9f1caad8c02..ef0de804196 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2016-08-08 Alan Modra + + PR target/72802 + * config/rs6000/rs6000.c (mem_operand_gpr): Remove vsx dform test. + (mem_operand_ds_form): New predicate. + * config/rs6000/rs6000-protos.h (mem_operand_ds_form): Declare. + * config/rs6000/constraints.md (wY): Use mem_operand_df_form. + * config/rs6000/predicates.md (offsettable_mem_14bit_operand): Delete. + * config/rs6000/rs6000.md (f32_lm2, f32_sm2): Use wY for SF. + (extendsfdf2_fpr): Replace o constraint with wY. + 2016-08-07 Jan Hubicka * tree-ssa-threadbackward.c: Include tree-inline.h diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md index 18713256b9b..7535c35155f 100644 --- a/gcc/config/rs6000/constraints.md +++ b/gcc/config/rs6000/constraints.md @@ -185,10 +185,14 @@ "Vector constant that can be loaded with XXSPLTIB & sign extension." (match_test "xxspltib_constant_split (op, mode)")) -;; ISA 3.0 D-form instruction that has the bottom 2 bits 0 (LXSD or STXSD). +;; ISA 3.0 DS-form instruction that has the bottom 2 bits 0 and no update form. +;; Used by LXSD/STXSD/LXSSP/STXSSP. In contrast to "Y", the multiple-of-four +;; offset is enforced for 32-bit too. (define_memory_constraint "wY" "Offsettable memory operand, with bottom 2 bits 0" - (match_operand 0 "offsettable_mem_14bit_operand")) + (and (match_code "mem") + (not (match_test "update_address_mem (op, mode)")) + (match_test "mem_operand_ds_form (op, mode)"))) ;; Altivec style load/store that ignores the bottom bits of the address (define_memory_constraint "wZ" diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 0d10e9ab5c1..6436d5eb3a1 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -734,15 +734,6 @@ (and (match_operand 0 "memory_operand") (match_test "offsettable_nonstrict_memref_p (op)"))) -;; Return 1 if the operand is an offsettable memory operand for ISA 3.0 -;; scalar LXSD/STXSD that must have the bottom 2 bits 0 and no update -;; form -(define_predicate "offsettable_mem_14bit_operand" - (and (match_operand 0 "memory_operand") - (match_test "offsettable_nonstrict_memref_p (op)") - (match_test "mem_operand_gpr (op, mode)") - (not (match_test "update_address_mem (op, mode)")))) - ;; Return 1 if the operand is suitable for load/store quad memory. ;; This predicate only checks for non-atomic loads/stores (not lqarx/stqcx). (define_predicate "quad_memory_operand" diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 8a307a85e6f..c7e338a8927 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -39,6 +39,7 @@ extern int num_insns_constant (rtx, machine_mode); extern int num_insns_constant_wide (HOST_WIDE_INT); extern int small_data_operand (rtx, machine_mode); extern bool mem_operand_gpr (rtx, machine_mode); +extern bool mem_operand_ds_form (rtx, machine_mode); extern bool toc_relative_expr_p (const_rtx, bool); extern bool invalid_e500_subreg (rtx, machine_mode); extern void validate_condition_mode (enum rtx_code, machine_mode); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 779ba1fb002..c59d07ac899 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -7717,8 +7717,34 @@ mem_operand_gpr (rtx op, machine_mode mode) if (TARGET_POWERPC64 && (offset & 3) != 0) return false; - if (mode_supports_vsx_dform_quad (mode) - && !quad_address_offset_p (offset)) + extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD; + if (extra < 0) + extra = 0; + + if (GET_CODE (addr) == LO_SUM) + /* For lo_sum addresses, we must allow any offset except one that + causes a wrap, so test only the low 16 bits. */ + offset = ((offset & 0xffff) ^ 0x8000) - 0x8000; + + return offset + 0x8000 < 0x10000u - extra; +} + +/* As above, but for DS-FORM VSX insns. Unlike mem_operand_gpr, + enforce an offset divisible by 4 even for 32-bit. */ + +bool +mem_operand_ds_form (rtx op, machine_mode mode) +{ + unsigned HOST_WIDE_INT offset; + int extra; + rtx addr = XEXP (op, 0); + + op = address_offset (addr); + if (op == NULL_RTX) + return true; + + offset = INTVAL (op); + if ((offset & 3) != 0) return false; extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD; diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index bc01dc7d2f0..1430799a04e 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -446,7 +446,7 @@ (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_lm2 [(SF "wY") (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")]) @@ -455,7 +455,7 @@ (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_sm2 [(SF "wY") (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")]) @@ -4538,7 +4538,7 @@ (define_insn_and_split "*extendsfdf2_fpr" [(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")))] + (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "@ # -- 2.30.2