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
This commit is contained in:
Andreas Krebbel 2005-08-12 12:24:05 +00:00 committed by Ulrich Weigand
parent c4d501291d
commit f83a336ddb
4 changed files with 71 additions and 4 deletions

View file

@ -1,3 +1,13 @@
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):

View file

@ -75,13 +75,59 @@
(and (match_test "mode == Pmode")
(match_test "!legitimate_la_operand_p (op)"))))
;; Return true if OP is a valid shift count operand.
;; Return true if OP is a valid operand for setmem.
(define_predicate "shift_count_operand"
(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, 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

View file

@ -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)

View file

@ -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))]