diff options
author | Andreas Krebbel <krebbel1@de.ibm.com> | 2005-08-12 12:24:05 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2005-08-12 12:24:05 +0000 |
commit | f83a336ddb52188f74051fbe440fd41694fd4658 (patch) | |
tree | dc94b3510d90c20e24e15cd81046fff83eabe3ed /gcc | |
parent | c4d501291d813840ad576842db00d9cfe9e77623 (diff) | |
download | gcc-f83a336ddb52188f74051fbe440fd41694fd4658.zip gcc-f83a336ddb52188f74051fbe440fd41694fd4658.tar.gz gcc-f83a336ddb52188f74051fbe440fd41694fd4658.tar.bz2 |
predicates.md (setmem_operand): New predicate.
2005-08-12 Andreas Krebbel <krebbel1@de.ibm.com>
* config/s390/predicates.md (setmem_operand): New predicate.
(shift_count_operand): Accept ANDs with special constants as
operand.
* config/s390/s390.c (print_shift_count_operand): Skip ANDs
with special constants.
* config/s390/s390.md ("setmem_long", "*setmem_long"): Replaced
shift_count_operand with setmem_operand.
From-SVN: r103028
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/s390/predicates.md | 48 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 11 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 4 |
4 files changed, 70 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8378a7f..9b8cf8a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2005-08-12 Andreas Krebbel <krebbel1@de.ibm.com> + * config/s390/predicates.md (setmem_operand): New predicate. + (shift_count_operand): Accept ANDs with special constants as + operand. + * config/s390/s390.c (print_shift_count_operand): Skip ANDs + with special constants. + * config/s390/s390.md ("setmem_long", "*setmem_long"): Replaced + shift_count_operand with setmem_operand. + +2005-08-12 Andreas Krebbel <krebbel1@de.ibm.com> + * config/s390/s390.c (s390_extract_part, s390_single_part): Type cast added. (s390_const_ok_for_constraint_p): Added SImode to the N constraint. diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md index fb8a9a4..05ef8c8 100644 --- a/gcc/config/s390/predicates.md +++ b/gcc/config/s390/predicates.md @@ -75,13 +75,59 @@ (and (match_test "mode == Pmode") (match_test "!legitimate_la_operand_p (op)")))) +;; Return true if OP is a valid operand for setmem. + +(define_predicate "setmem_operand" + (match_code "reg, subreg, plus, const_int") +{ + HOST_WIDE_INT offset = 0; + + /* The padding byte operand of the mvcle instruction is always truncated + to the 8 least significant bits. */ + if (GET_CODE (op) == AND && GET_CODE (XEXP (op, 1)) == CONST_INT + && (INTVAL (XEXP (op, 1)) & 255) == 255) + op = XEXP (op, 0); + + /* We can have an integer constant, an address register, + or a sum of the two. Note that reload already checks + that any register present is an address register, so + we just check for any register here. */ + if (GET_CODE (op) == CONST_INT) + { + offset = INTVAL (op); + op = NULL_RTX; + } + if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT) + { + offset = INTVAL (XEXP (op, 1)); + op = XEXP (op, 0); + } + while (op && GET_CODE (op) == SUBREG) + op = SUBREG_REG (op); + if (op && GET_CODE (op) != REG) + return false; + + /* Unfortunately we have to reject constants that are invalid + for an address, or else reload will get confused. */ + if (!DISP_IN_RANGE (offset)) + return false; + + return true; +}) + ;; Return true if OP is a valid shift count operand. (define_predicate "shift_count_operand" - (match_code "reg, subreg, plus, const_int") + (match_code "reg, subreg, plus, const_int, and") { HOST_WIDE_INT offset = 0; + /* Shift count operands are always truncated to the 6 least significant bits. + So we can accept pointless ANDs here. */ + if (GET_CODE (op) == AND && GET_CODE (XEXP (op, 1)) == CONST_INT + && (INTVAL (XEXP (op, 1)) & 63) == 63) + op = XEXP (op, 0); + /* We can have an integer constant, an address register, or a sum of the two. Note that reload already checks that any register present is an address register, so diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 551ffed..277006f 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -3758,6 +3758,17 @@ print_shift_count_operand (FILE *file, rtx op) { HOST_WIDE_INT offset = 0; + /* Shift count operands are always truncated to the 6 least significant bits and + the setmem padding byte to the least 8 significant bits. Hence we can drop + pointless ANDs. */ + if (GET_CODE (op) == AND && GET_CODE (XEXP (op, 1)) == CONST_INT) + { + if ((INTVAL (XEXP (op, 1)) & 63) != 63) + gcc_unreachable (); + + op = XEXP (op, 0); + } + /* We can have an integer constant, an address register, or a sum of the two. */ if (GET_CODE (op) == CONST_INT) diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index ee87cf6..c09df12 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -2062,7 +2062,7 @@ [(parallel [(clobber (match_dup 1)) (set (match_operand:BLK 0 "memory_operand" "") - (match_operand 2 "shift_count_operand" "")) + (match_operand 2 "setmem_operand" "")) (use (match_operand 1 "general_operand" "")) (use (match_dup 3)) (clobber (reg:CC CC_REGNUM))])] @@ -2088,7 +2088,7 @@ (define_insn "*setmem_long" [(clobber (match_operand:<DBL> 0 "register_operand" "=d")) (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0)) - (match_operand 2 "shift_count_operand" "Y")) + (match_operand 2 "setmem_operand" "Y")) (use (match_dup 3)) (use (match_operand:<DBL> 1 "register_operand" "d")) (clobber (reg:CC CC_REGNUM))] |