From 2e5251888527a5bbf222a02166432959eb42dc0e Mon Sep 17 00:00:00 2001 From: dje Date: Thu, 11 Aug 2005 21:18:11 +0000 Subject: [PATCH] * config/rs6000/altivec.md: Change constraint "m" to "Z". * config/rs6000/predicates.md (indexed_or_indirect_operand): Accept address wrapped in AND for Altivec. * config/rs6000/rs6000.c (rs6000_legitimize_reload_address): Strip AND wrapping offset address for Altivec. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103001 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++++ gcc/config/rs6000/altivec.md | 28 ++++++++++++++-------------- gcc/config/rs6000/predicates.md | 21 ++++++++++++++++----- gcc/config/rs6000/rs6000.c | 17 +++++++++++++++++ 4 files changed, 55 insertions(+), 19 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2643e608f04..cbf54d471c6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2005-08-11 David Edelsohn + + * config/rs6000/altivec.md: Change constraint "m" to "Z". + * config/rs6000/predicates.md (indexed_or_indirect_operand): + Accept address wrapped in AND for Altivec. + * config/rs6000/rs6000.c (rs6000_legitimize_reload_address): + Strip AND wrapping offset address for Altivec. + 2005-08-11 Richard Henderson PR middle-end/23312 diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 2b03502172c..02524355703 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -149,14 +149,14 @@ ;; Generic LVX load instruction. (define_insn "altivec_lvx_" [(set (match_operand:V 0 "altivec_register_operand" "=v") - (match_operand:V 1 "memory_operand" "m"))] + (match_operand:V 1 "memory_operand" "Z"))] "TARGET_ALTIVEC" "lvx %0,%y1" [(set_attr "type" "vecload")]) ;; Generic STVX store instruction. (define_insn "altivec_stvx_" - [(set (match_operand:V 0 "memory_operand" "=m") + [(set (match_operand:V 0 "memory_operand" "=Z") (match_operand:V 1 "altivec_register_operand" "v"))] "TARGET_ALTIVEC" "stvx %1,%y0" @@ -173,8 +173,8 @@ }) (define_insn "*mov_internal" - [(set (match_operand:V 0 "nonimmediate_operand" "=m,v,v,o,r,r,v") - (match_operand:V 1 "input_operand" "v,m,v,r,o,r,W"))] + [(set (match_operand:V 0 "nonimmediate_operand" "=Z,v,v,o,r,r,v") + (match_operand:V 1 "input_operand" "v,Z,v,r,o,r,W"))] "TARGET_ALTIVEC && (register_operand (operands[0], mode) || register_operand (operands[1], mode))" @@ -1802,21 +1802,21 @@ (define_insn "altivec_lvsl" [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand 1 "memory_operand" "m")] UNSPEC_LVSL))] + (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSL))] "TARGET_ALTIVEC" "lvsl %0,%y1" [(set_attr "type" "vecload")]) (define_insn "altivec_lvsr" [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand 1 "memory_operand" "m")] UNSPEC_LVSR))] + (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSR))] "TARGET_ALTIVEC" "lvsr %0,%y1" [(set_attr "type" "vecload")]) (define_expand "build_vector_mask_for_load" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand 1 "memory_operand" "m")] UNSPEC_LVSR))] + [(set (match_operand:V16QI 0 "register_operand" "") + (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))] "TARGET_ALTIVEC" " { @@ -1858,7 +1858,7 @@ (define_insn "altivec_lvxl" [(parallel [(set (match_operand:V4SI 0 "register_operand" "=v") - (match_operand:V4SI 1 "memory_operand" "m")) + (match_operand:V4SI 1 "memory_operand" "Z")) (unspec [(const_int 0)] UNSPEC_SET_VSCR)])] "TARGET_ALTIVEC" "lvxl %0,%y1" @@ -1866,14 +1866,14 @@ (define_insn "altivec_lvx" [(set (match_operand:V4SI 0 "register_operand" "=v") - (match_operand:V4SI 1 "memory_operand" "m"))] + (match_operand:V4SI 1 "memory_operand" "Z"))] "TARGET_ALTIVEC" "lvx %0,%y1" [(set_attr "type" "vecload")]) (define_insn "altivec_stvx" [(parallel - [(set (match_operand:V4SI 0 "memory_operand" "=m") + [(set (match_operand:V4SI 0 "memory_operand" "=Z") (match_operand:V4SI 1 "register_operand" "v")) (unspec [(const_int 0)] UNSPEC_STVX)])] "TARGET_ALTIVEC" @@ -1882,7 +1882,7 @@ (define_insn "altivec_stvxl" [(parallel - [(set (match_operand:V4SI 0 "memory_operand" "=m") + [(set (match_operand:V4SI 0 "memory_operand" "=Z") (match_operand:V4SI 1 "register_operand" "v")) (unspec [(const_int 0)] UNSPEC_STVXL)])] "TARGET_ALTIVEC" @@ -1891,7 +1891,7 @@ (define_insn "altivec_stvex" [(parallel - [(set (match_operand:VI 0 "memory_operand" "=m") + [(set (match_operand:VI 0 "memory_operand" "=Z") (match_operand:VI 1 "register_operand" "v")) (unspec [(const_int 0)] UNSPEC_STVE)])] "TARGET_ALTIVEC" @@ -1900,7 +1900,7 @@ (define_insn "*altivec_stvesfx" [(parallel - [(set (match_operand:V4SF 0 "memory_operand" "=m") + [(set (match_operand:V4SF 0 "memory_operand" "=Z") (match_operand:V4SF 1 "register_operand" "v")) (unspec [(const_int 0)] UNSPEC_STVE)])] "TARGET_ALTIVEC" diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 68c824a077f..122ec45e856 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -355,11 +355,22 @@ ;; Return 1 if the operand is an indexed or indirect memory operand. (define_predicate "indexed_or_indirect_operand" - (and (match_operand 0 "memory_operand") - (match_test "REG_P (XEXP (op, 0)) - || (GET_CODE (XEXP (op, 0)) == PLUS - && REG_P (XEXP (XEXP (op, 0), 0)) - && REG_P (XEXP (XEXP (op, 0), 1)))"))) + (match_operand 0 "memory_operand") +{ + rtx tmp = XEXP (op, 0); + + if (TARGET_ALTIVEC + && ALTIVEC_VECTOR_MODE (mode) + && GET_CODE (tmp) == AND + && GET_CODE (XEXP (tmp, 1)) == CONST_INT + && INTVAL (XEXP (tmp, 1)) == -16) + tmp = XEXP (tmp, 0); + + return REG_P (tmp) + || (GET_CODE (tmp) == PLUS + && REG_P (XEXP (tmp, 0)) + && REG_P (XEXP (tmp, 1))); +}) ;; Return 1 if the operand is a memory operand with an address divisible by 4 (define_predicate "word_offset_memref_operand" diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 577bbfbbf81..04c02c35377 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -3332,6 +3332,23 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, } #endif + /* Reload an offset address wrapped by an AND that represents the + masking of the lower bits. Strip the outer AND and let reload + convert the offset address into an indirect address. */ + if (TARGET_ALTIVEC + && ALTIVEC_VECTOR_MODE (mode) + && GET_CODE (x) == AND + && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT + && GET_CODE (XEXP (x, 1)) == CONST_INT + && INTVAL (XEXP (x, 1)) == -16) + { + x = XEXP (x, 0); + *win = 1; + return x; + } + if (TARGET_TOC && constant_pool_expr_p (x) && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode)) -- 2.11.0