diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8d26a00c153..76b4af76da7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2004-11-09 Ulrich Weigand + + * config/s390/s390-protos.h (s390_pool_operand): Remove. + * config/s390/s390.c (s390_pool_operand): Likewise. + (s390_extra_constraint_str): Handle 'B' constraints. + * config/s390/s390.h (CONSTRAINT_LEN): Handle 'B' constraints. + * config/s390/s390.md: Document 'B' constraints. + ("*cmpdi_cct", "*cmpsi_cct"): Use 'B' constraint instead of + s390_pool_operand to prevent insns with two literal pool + references. Make pattern commutative. + ("*cmpdi_ccu", "*cmpsi_ccu", "*cmphi_ccu", "*cmpqi_ccu"): Use + 'B' constraint instead of s390_pool_operand. + 2004-11-09 Kazu Hirata * tree-cfg.c (create_bb): Remove unnecessary memset. diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 3b21d03fcb3..25aeef86991 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -89,7 +89,6 @@ extern void s390_expand_logical_operator (enum rtx_code, enum machine_mode, rtx *); extern bool s390_logical_operator_ok_p (rtx *); extern void s390_narrow_logical_operator (enum rtx_code, rtx *, rtx *); -extern bool s390_pool_operand (rtx); extern void s390_split_access_reg (rtx, rtx *, rtx *); extern bool s390_output_addr_const_extra (FILE*, rtx); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 42636c44a5f..a6f0d64dc7b 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -1508,41 +1508,6 @@ s_operand (rtx op, enum machine_mode mode) return 1; } -/* Return true if OP is a memory operand pointing to the - literal pool, or an immediate operand. */ - -bool -s390_pool_operand (rtx op) -{ - struct s390_address addr; - - /* Just like memory_operand, allow (subreg (mem ...)) - after reload. */ - if (reload_completed - && GET_CODE (op) == SUBREG - && GET_CODE (SUBREG_REG (op)) == MEM) - op = SUBREG_REG (op); - - switch (GET_CODE (op)) - { - case CONST_INT: - case CONST_DOUBLE: - return true; - - case MEM: - if (!s390_decompose_address (XEXP (op, 0), &addr)) - return false; - if (addr.base && REG_P (addr.base) && REGNO (addr.base) == BASE_REGNUM) - return true; - if (addr.indx && REG_P (addr.indx) && REGNO (addr.indx) == BASE_REGNUM) - return true; - return false; - - default: - return false; - } -} - /* Return true if OP a valid shift count operand. OP is the current operation. MODE is the current operation mode. */ @@ -1634,6 +1599,21 @@ s390_extra_constraint_str (rtx op, int c, const char * str) c = str[1]; } + /* Check for non-literal-pool variants of memory constraints. */ + else if (c == 'B') + { + if (GET_CODE (op) != MEM) + return 0; + if (!s390_decompose_address (XEXP (op, 0), &addr)) + return 0; + if (addr.base && REG_P (addr.base) && REGNO (addr.base) == BASE_REGNUM) + return 0; + if (addr.indx && REG_P (addr.indx) && REGNO (addr.indx) == BASE_REGNUM) + return 0; + + c = str[1]; + } + switch (c) { case 'Q': diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 0116a662340..694dcb81717 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -583,7 +583,8 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; #define CONSTRAINT_LEN(C, STR) \ ((C) == 'N' ? 5 : \ - (C) == 'A' ? 2 : DEFAULT_CONSTRAINT_LEN ((C), (STR))) + (C) == 'A' ? 2 : \ + (C) == 'B' ? 2 : DEFAULT_CONSTRAINT_LEN ((C), (STR))) /* Stack layout and calling conventions. */ diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 15180087133..dbeaea4678b 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -50,6 +50,9 @@ ;; T -- Memory reference with index register and long displacement. ;; A -- Multiple letter constraint followed by Q, R, S, or T: ;; Offsettable memory reference of type specified by second letter. +;; B -- Multiple letter constraint followed by Q, R, S, or T: +;; Memory reference of the type specified by second letter that +;; does *not* refer to a literal pool entry. ;; U -- Pointer with short displacement. ;; W -- Pointer with long displacement. ;; Y -- Shift count operand. @@ -525,33 +528,28 @@ (define_insn "*cmpdi_cct" [(set (reg 33) - (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,d,m,Q") - (match_operand:DI 1 "general_operand" "d,K,m,d,Q")))] - "s390_match_ccmode (insn, CCTmode) && TARGET_64BIT - && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1]))" + (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,Q") + (match_operand:DI 1 "general_operand" "d,K,m,BQ")))] + "s390_match_ccmode (insn, CCTmode) && TARGET_64BIT" "@ cgr\t%0,%1 cghi\t%0,%c1 cg\t%0,%1 - cg\t%1,%0 #" - [(set_attr "op_type" "RRE,RI,RXY,RXY,SS")]) + [(set_attr "op_type" "RRE,RI,RXY,SS")]) (define_insn "*cmpsi_cct" [(set (reg 33) - (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,d,R,T,Q") - (match_operand:SI 1 "general_operand" "d,K,R,T,d,d,Q")))] - "s390_match_ccmode (insn, CCTmode) - && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1]))" + (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,Q") + (match_operand:SI 1 "general_operand" "d,K,R,T,BQ")))] + "s390_match_ccmode (insn, CCTmode)" "@ cr\t%0,%1 chi\t%0,%c1 c\t%0,%1 cy\t%0,%1 - c\t%1,%0 - cy\t%1,%0 #" - [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS")]) + [(set_attr "op_type" "RR,RI,RX,RXY,SS")]) ; Compare (signed) instructions @@ -614,56 +612,56 @@ (define_insn "*cmpdi_ccu" [(set (reg 33) - (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,Q") - (match_operand:DI 1 "general_operand" "d,m,Q")))] - "s390_match_ccmode (insn, CCUmode) && TARGET_64BIT - && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1]))" + (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,Q,BQ") + (match_operand:DI 1 "general_operand" "d,m,BQ,Q")))] + "s390_match_ccmode (insn, CCUmode) && TARGET_64BIT" "@ clgr\t%0,%1 clg\t%0,%1 + # #" - [(set_attr "op_type" "RRE,RXY,SS")]) + [(set_attr "op_type" "RRE,RXY,SS,SS")]) (define_insn "*cmpsi_ccu" [(set (reg 33) - (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,Q") - (match_operand:SI 1 "general_operand" "d,R,T,Q")))] - "s390_match_ccmode (insn, CCUmode) - && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1]))" + (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,Q,BQ") + (match_operand:SI 1 "general_operand" "d,R,T,BQ,Q")))] + "s390_match_ccmode (insn, CCUmode)" "@ clr\t%0,%1 cl\t%0,%1 cly\t%0,%1 + # #" - [(set_attr "op_type" "RR,RX,RXY,SS")]) + [(set_attr "op_type" "RR,RX,RXY,SS,SS")]) (define_insn "*cmphi_ccu" [(set (reg 33) - (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q") - (match_operand:HI 1 "general_operand" "Q,S,Q")))] + (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,BQ") + (match_operand:HI 1 "general_operand" "Q,S,BQ,Q")))] "s390_match_ccmode (insn, CCUmode) - && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1])) && !register_operand (operands[1], HImode)" "@ clm\t%0,3,%S1 clmy\t%0,3,%S1 + # #" - [(set_attr "op_type" "RS,RSY,SS")]) + [(set_attr "op_type" "RS,RSY,SS,SS")]) (define_insn "*cmpqi_ccu" [(set (reg 33) - (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q") - (match_operand:QI 1 "general_operand" "Q,S,n,n,Q")))] + (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ") + (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))] "s390_match_ccmode (insn, CCUmode) - && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1])) && !register_operand (operands[1], QImode)" "@ clm\t%0,1,%S1 clmy\t%0,1,%S1 cli\t%S0,%b1 cliy\t%S0,%b1 + # #" - [(set_attr "op_type" "RS,RSY,SI,SIY,SS")]) + [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")]) ; Block compare (CLC) instruction patterns. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d63447e978a..66df19999b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-11-09 Ulrich Weigand + + * gcc.dg/20041109-1.c: New test. + 2004-11-09 Andrew Pinski PR objc/18406 diff --git a/gcc/testsuite/gcc.dg/20041109-1.c b/gcc/testsuite/gcc.dg/20041109-1.c new file mode 100644 index 00000000000..8b072339dd8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20041109-1.c @@ -0,0 +1,21 @@ +/* This used to ICE due to a literal pool handling bug on s390x. */ + +/* { dg-do compile { target s390*-*-* } } */ +/* { dg-options "-O2 -fno-omit-frame-pointer" } */ + +static struct table { int x; } table[3]; + +int test (void) +{ + struct table *t; + + for (t = table; t < &table[3]; t++) + asm volatile ("" : : : "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "12"); + + for (t = table; t < &table[3]; t++) + if (t->x) + return 1; + + return 0; +} +