constraints.md: New file.

* config/h8300/constraints.md: New file.
	* config/h8300/h8300.md: Include it.  Use satisfies_constraint_J,
	satisfies_constraint_L, and satisfies_constraint_N for peephole2s.
	(*tst_extzv_1_n, *tstsi_variable_bit_qi): Use satisfies_constraint_U.
	* config/h8300/predicates.md (bit_operand): Likewise.
	(incdec_operand): Use satisfies_constraint_M and
	satisfies_constraint_O.  Don't use C code block.
	* config/h8300/h8300-protos.h (h8300_reg_class_from_letter): Delete.
	* config/h8300/h8300.c (h8300_reg_class_from_letter): Delete.
	(compute_mov_length): Use satisfies_constraint_G.
	(fix_bit_operand): Use satisfies_constraint_U.
	* config/h8300/h8300.h (REG_CLASS_FROM_LETTER): Delete.
	(CONST_OK_FOR_I, CONST_OK_FOR_J, CONST_OK_FOR_L): Delete.
	(CONST_OK_FOR_M, CONST_OK_FOR_N, CONST_OK_FOR_O): Delete.
	(CONST_OK_FOR_Ppositive, CONST_OK_FOR_Pnegative): Delete.
	(CONST_OK_FOR_P, CONSTRAINT_LEN_FOR_P): Delete.
	(CONST_OK_FOR_CONSTRAINT_P, CONST_OK_FOR_LETTER_P): Delete.
	(CONST_DOUBLE_OK_FOR_LETTER_P): Delete.
	(OK_FOR_Q, OK_FOR_R, OK_FOR_S, OK_FOR_T, OK_FOR_U, OK_FOR_WU): Delete.
	(OK_FOR_W, CONSTRAINT_LEN_FOR_W, OK_FOR_Y2, OK_FOR_Y0): Delete.
	(OK_FOR_Y, CONSTRAINT_LEN_FOR_Y, OK_FOR_Z): Delete.
	(EXTRA_CONSTRAINT_STR, CONSTRAINT_LEN): Delete.
	(EXTRA_MEMORY_CONSTRAINT): Delete.

From-SVN: r171851
This commit is contained in:
Nathan Froyd 2011-04-01 20:08:22 +00:00 committed by Nathan Froyd
parent c1c0e8e1d3
commit ceaaaeabf6
6 changed files with 261 additions and 273 deletions

View File

@ -1,3 +1,29 @@
2011-04-01 Nathan Froyd <froydnj@codesourcery.com>
* config/h8300/constraints.md: New file.
* config/h8300/h8300.md: Include it. Use satisfies_constraint_J,
satisfies_constraint_L, and satisfies_constraint_N for peephole2s.
(*tst_extzv_1_n, *tstsi_variable_bit_qi): Use satisfies_constraint_U.
* config/h8300/predicates.md (bit_operand): Likewise.
(incdec_operand): Use satisfies_constraint_M and
satisfies_constraint_O. Don't use C code block.
* config/h8300/h8300-protos.h (h8300_reg_class_from_letter): Delete.
* config/h8300/h8300.c (h8300_reg_class_from_letter): Delete.
(compute_mov_length): Use satisfies_constraint_G.
(fix_bit_operand): Use satisfies_constraint_U.
* config/h8300/h8300.h (REG_CLASS_FROM_LETTER): Delete.
(CONST_OK_FOR_I, CONST_OK_FOR_J, CONST_OK_FOR_L): Delete.
(CONST_OK_FOR_M, CONST_OK_FOR_N, CONST_OK_FOR_O): Delete.
(CONST_OK_FOR_Ppositive, CONST_OK_FOR_Pnegative): Delete.
(CONST_OK_FOR_P, CONSTRAINT_LEN_FOR_P): Delete.
(CONST_OK_FOR_CONSTRAINT_P, CONST_OK_FOR_LETTER_P): Delete.
(CONST_DOUBLE_OK_FOR_LETTER_P): Delete.
(OK_FOR_Q, OK_FOR_R, OK_FOR_S, OK_FOR_T, OK_FOR_U, OK_FOR_WU): Delete.
(OK_FOR_W, CONSTRAINT_LEN_FOR_W, OK_FOR_Y2, OK_FOR_Y0): Delete.
(OK_FOR_Y, CONSTRAINT_LEN_FOR_Y, OK_FOR_Z): Delete.
(EXTRA_CONSTRAINT_STR, CONSTRAINT_LEN): Delete.
(EXTRA_MEMORY_CONSTRAINT): Delete.
2011-04-01 Andrew Pinski <pinskia@gmail.com> 2011-04-01 Andrew Pinski <pinskia@gmail.com>
Michael Meissner <meissner@linux.vnet.ibm.com> Michael Meissner <meissner@linux.vnet.ibm.com>

View File

@ -0,0 +1,214 @@
;; Constraint definitions for Renesas H8/300.
;; Copyright (C) 2011 Free Software Foundation, Inc.
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; GCC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
;; Register constraints.
(define_register_constraint "a" "MAC_REGS"
"@internal")
(define_register_constraint "c" "COUNTER_REGS"
"@internal")
;; Some patterns need to use er6 as a scratch register. This is
;; difficult to arrange since er6 is the frame pointer and usually can't
;; be spilled.
;; Such patterns should define two alternatives, one which allows only
;; er6 and one which allows any general register. The former
;; alternative should have a 'd' constraint while the latter should be
;; disparaged and use 'D'.
;; Normally, 'd' maps to DESTINATION_REGS and 'D' maps to GENERAL_REGS.
;; However, there are cases where they should be NO_REGS:
;; - 'd' should be NO_REGS when reloading a function that uses the
;; frame pointer. In this case, DESTINATION_REGS won't contain any
;; spillable registers, so the first alternative can't be used.
;; - -fno-omit-frame-pointer means that the frame pointer will
;; always be in use. It's therefore better to map 'd' to NO_REGS
;; before reload so that register allocator will pick the second
;; alternative.
;; - we would like 'D' to be be NO_REGS when the frame pointer isn't
;; live, but we the frame pointer may turn out to be needed after
;; we start reload, and then we may have already decided we don't
;; have a choice, so we can't do that. Forcing the register
;; allocator to use er6 if possible might produce better code for
;; small functions: it's more efficient to save and restore er6 in
;; the prologue & epilogue than to do it in a define_split.
;; Hopefully disparaging 'D' will have a similar effect, without
;; forcing a reload failure if the frame pointer is found to be
;; needed too late.
(define_register_constraint "d"
"(!flag_omit_frame_pointer && !reload_completed
? NO_REGS
: (frame_pointer_needed && reload_in_progress
? NO_REGS
: DESTINATION_REGS))"
"@internal")
(define_register_constraint "D" "GENERAL_REGS"
"@internal")
(define_register_constraint "f" "SOURCE_REGS"
"@internal")
;; Integer constraints.
(define_constraint "I"
"Integer zero."
(and (match_code "const_int")
(match_test "ival == 0")))
(define_constraint "J"
"An integer with its low byte clear."
(and (match_code "const_int")
(match_test "(ival & 0xff) == 0")))
(define_constraint "L"
"1, 2 or 4 on the H8300H or S; 1 or 2 otherwise."
(and (match_code "const_int")
(if_then_else (match_test "TARGET_H8300H || TARGET_H8300S")
(match_test "ival == 1 || ival == 2 || ival == 4")
(match_test "ival == 1 || ival == 2"))))
(define_constraint "M"
"Integer 1 or 2."
(and (match_code "const_int")
(match_test "ival == 1 || ival == 2")))
(define_constraint "N"
"-1, -2, or -4 on the H8300H or S; -1 or -2 otherwise."
(and (match_code "const_int")
(if_then_else (match_test "TARGET_H8300H || TARGET_H8300S")
(match_test "ival == -1 || ival == -2 || ival == -4")
(match_test "ival == -1 || ival == -2"))))
(define_constraint "O"
"Integer -1 or -2."
(and (match_code "const_int")
(match_test "ival == -1 || ival == -2")))
(define_constraint "P1>X"
"A positive, non-zero integer that fits in 1 bits."
(and (match_code "const_int")
(match_test "TARGET_H8300SX")
(match_test "IN_RANGE (ival, 1, (1 << 1) - 1)")))
(define_constraint "P3>X"
"A positive, non-zero integer that fits in 3 bits."
(and (match_code "const_int")
(match_test "TARGET_H8300SX")
(match_test "IN_RANGE (ival, 1, (1 << 3) - 1)")))
(define_constraint "P4>X"
"A positive, non-zero integer that fits in 4 bits."
(and (match_code "const_int")
(match_test "TARGET_H8300SX")
(match_test "IN_RANGE (ival, 1, (1 << 4) - 1)")))
(define_constraint "P5>X"
"A positive, non-zero integer that fits in 5 bits."
(and (match_code "const_int")
(match_test "TARGET_H8300SX")
(match_test "IN_RANGE (ival, 1, (1 << 5) - 1)")))
(define_constraint "P8>X"
"A positive, non-zero integer that fits in 8 bits."
(and (match_code "const_int")
(match_test "TARGET_H8300SX")
(match_test "IN_RANGE (ival, 1, (1 << 8) - 1)")))
(define_constraint "P3<X"
"A negative, non-zero integer that fits in 3 bits."
(and (match_code "const_int")
(match_test "TARGET_H8300SX")
(match_test "IN_RANGE (ival, (-(1 << 3)) + 1, -1)")))
;; Floating-point constraints.
(define_constraint "G"
"Single-float zero."
(and (match_code "const_double")
(match_test "op == CONST0_RTX (SFmode)")))
;; Extra constraints.
(define_constraint "Q"
"@internal"
(and (match_test "TARGET_H8300SX")
(match_operand 0 "memory_operand")))
(define_constraint "R"
"@internal"
(and (match_code "const_int")
(match_test "!h8300_shift_needs_scratch_p (ival, QImode)")))
(define_constraint "S"
"@internal"
(and (match_code "const_int")
(match_test "!h8300_shift_needs_scratch_p (ival, HImode)")))
(define_constraint "T"
"@internal"
(and (match_code "const_int")
(match_test "!h8300_shift_needs_scratch_p (ival, SImode)")))
(define_constraint "U"
"An operand valid for a bset destination."
(ior (and (match_code "reg")
(match_test "REG_OK_FOR_BASE_P (op)"))
(and (match_code "mem")
(match_code "reg" "0")
(match_test "REG_OK_FOR_BASE_P (XEXP (op, 0))"))
(and (match_code "mem")
(match_code "symbol_ref" "0")
(match_test "TARGET_H8300S"))
(and (match_code "mem")
(match_code "const" "0")
(match_code "plus" "00")
(match_code "symbol_ref" "000")
(match_code "const_int" "001")
(ior (match_test "TARGET_H8300S")
(match_test "SYMBOL_REF_FLAG (XEXP (XEXP (XEXP (op, 0), 0), 0))")))
(and (match_code "mem")
(match_test "h8300_eightbit_constant_address_p (XEXP (op, 0))"))
(and (match_code "mem")
(ior (match_test "TARGET_H8300S")
(match_test "TARGET_H8300SX"))
(match_code "const_int" "0"))))
(define_memory_constraint "WU"
"@internal"
(and (match_code "mem")
(match_test "satisfies_constraint_U (op)")))
(define_constraint "Y0"
"@internal"
(and (match_code "const_int")
(match_test "exact_log2 (~ival & 0xff) != -1")))
(define_constraint "Y2"
"@internal"
(and (match_code "const_int")
(match_test "exact_log2 (ival & 0xff) != -1")))
(define_constraint "Z"
"@internal"
(and (match_test "TARGET_H8300SX")
(match_code "mem")
(match_test "CONSTANT_P (XEXP (op, 0))")))

View File

@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h" #include "diagnostic-core.h"
#include "c-family/c-pragma.h" /* ??? */ #include "c-family/c-pragma.h" /* ??? */
#include "tm_p.h" #include "tm_p.h"
#include "tm-constrs.h"
#include "ggc.h" #include "ggc.h"
#include "target.h" #include "target.h"
#include "target-def.h" #include "target-def.h"
@ -421,71 +422,6 @@ h8300_option_override (void)
flag_strict_volatile_bitfields = 1; flag_strict_volatile_bitfields = 1;
} }
/* Implement REG_CLASS_FROM_LETTER.
Some patterns need to use er6 as a scratch register. This is
difficult to arrange since er6 is the frame pointer and usually
can't be spilled.
Such patterns should define two alternatives, one which allows only
er6 and one which allows any general register. The former alternative
should have a 'd' constraint while the latter should be disparaged and
use 'D'.
Normally, 'd' maps to DESTINATION_REGS and 'D' maps to GENERAL_REGS.
However, there are cases where they should be NO_REGS:
- 'd' should be NO_REGS when reloading a function that uses the
frame pointer. In this case, DESTINATION_REGS won't contain any
spillable registers, so the first alternative can't be used.
- -fno-omit-frame-pointer means that the frame pointer will
always be in use. It's therefore better to map 'd' to NO_REGS
before reload so that register allocator will pick the second
alternative.
- we would like 'D' to be be NO_REGS when the frame pointer isn't
live, but we the frame pointer may turn out to be needed after
we start reload, and then we may have already decided we don't
have a choice, so we can't do that. Forcing the register
allocator to use er6 if possible might produce better code for
small functions: it's more efficient to save and restore er6 in
the prologue & epilogue than to do it in a define_split.
Hopefully disparaging 'D' will have a similar effect, without
forcing a reload failure if the frame pointer is found to be
needed too late. */
enum reg_class
h8300_reg_class_from_letter (int c)
{
switch (c)
{
case 'a':
return MAC_REGS;
case 'c':
return COUNTER_REGS;
case 'd':
if (!flag_omit_frame_pointer && !reload_completed)
return NO_REGS;
if (frame_pointer_needed && reload_in_progress)
return NO_REGS;
return DESTINATION_REGS;
case 'D':
/* The meaning of a constraint shouldn't change dynamically, so
we can't make this NO_REGS. */
return GENERAL_REGS;
case 'f':
return SOURCE_REGS;
default:
return NO_REGS;
}
}
/* Return the byte register name for a register rtx X. B should be 0 /* Return the byte register name for a register rtx X. B should be 0
if you want a lower byte register. B should be 1 if you want an if you want a lower byte register. B should be 1 if you want an
upper byte register. */ upper byte register. */
@ -2827,7 +2763,7 @@ compute_mov_length (rtx *operands)
if (REG_P (src)) if (REG_P (src))
return 4; return 4;
if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G')) if (satisfies_constraint_G (src))
return 4; return 4;
return 8; return 8;
@ -2947,7 +2883,7 @@ compute_mov_length (rtx *operands)
if (REG_P (src)) if (REG_P (src))
return 2; return 2;
if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G')) if (satisfies_constraint_G (src))
return 2; return 2;
return 6; return 6;
@ -5186,7 +5122,7 @@ fix_bit_operand (rtx *operands, enum rtx_code code)
{ {
/* OK to have a memory dest. */ /* OK to have a memory dest. */
if (GET_CODE (operands[0]) == MEM if (GET_CODE (operands[0]) == MEM
&& !OK_FOR_U (operands[0])) && !satisfies_constraint_U (operands[0]))
{ {
rtx mem = gen_rtx_MEM (GET_MODE (operands[0]), rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
copy_to_mode_reg (Pmode, copy_to_mode_reg (Pmode,
@ -5196,7 +5132,7 @@ fix_bit_operand (rtx *operands, enum rtx_code code)
} }
if (GET_CODE (operands[1]) == MEM if (GET_CODE (operands[1]) == MEM
&& !OK_FOR_U (operands[1])) && !satisfies_constraint_U (operands[1]))
{ {
rtx mem = gen_rtx_MEM (GET_MODE (operands[1]), rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
copy_to_mode_reg (Pmode, copy_to_mode_reg (Pmode,

View File

@ -357,76 +357,6 @@ enum reg_class {
#define INDEX_REG_CLASS (TARGET_H8300SX ? GENERAL_REGS : NO_REGS) #define INDEX_REG_CLASS (TARGET_H8300SX ? GENERAL_REGS : NO_REGS)
#define BASE_REG_CLASS GENERAL_REGS #define BASE_REG_CLASS GENERAL_REGS
/* Get reg_class from a letter such as appears in the machine description.
'a' is the MAC register. */
#define REG_CLASS_FROM_LETTER(C) (h8300_reg_class_from_letter (C))
/* The letters I, J, K, L, M, N, O, P in a register constraint string
can be used to stand for particular ranges of immediate operands.
This macro defines what the ranges are.
C is the letter, and VALUE is a constant value.
Return 1 if VALUE is in the range specified by C. */
#define CONST_OK_FOR_I(VALUE) ((VALUE) == 0)
#define CONST_OK_FOR_J(VALUE) (((VALUE) & 0xff) == 0)
#define CONST_OK_FOR_L(VALUE) \
(TARGET_H8300H || TARGET_H8300S \
? (VALUE) == 1 || (VALUE) == 2 || (VALUE) == 4 \
: (VALUE) == 1 || (VALUE) == 2)
#define CONST_OK_FOR_M(VALUE) \
((VALUE) == 1 || (VALUE) == 2)
#define CONST_OK_FOR_N(VALUE) \
(TARGET_H8300H || TARGET_H8300S \
? (VALUE) == -1 || (VALUE) == -2 || (VALUE) == -4 \
: (VALUE) == -1 || (VALUE) == -2)
#define CONST_OK_FOR_O(VALUE) \
((VALUE) == -1 || (VALUE) == -2)
/* Multi-letter constraints for constant are always started with P
(just because it was the only letter in the range left. New
constraints for constants should be added here. */
#define CONST_OK_FOR_Ppositive(VALUE, NBITS) \
((VALUE) > 0 && (VALUE) < (1 << (NBITS)))
#define CONST_OK_FOR_Pnegative(VALUE, NBITS) \
((VALUE) < 0 && (VALUE) > -(1 << (NBITS)))
#define CONST_OK_FOR_P(VALUE, STR) \
((STR)[1] >= '1' && (STR)[1] <= '9' && (STR)[2] == '<' \
? (((STR)[3] == '0' || ((STR)[3] == 'X' && TARGET_H8300SX)) \
&& CONST_OK_FOR_Pnegative ((VALUE), (STR)[1] - '0')) \
: ((STR)[1] >= '1' && (STR)[1] <= '9' && (STR)[2] == '>') \
? (((STR)[3] == '0' || ((STR)[3] == 'X' && TARGET_H8300SX)) \
&& CONST_OK_FOR_Ppositive ((VALUE), (STR)[1] - '0')) \
: 0)
#define CONSTRAINT_LEN_FOR_P(STR) \
((((STR)[1] >= '1' && (STR)[1] <= '9') \
&& ((STR)[2] == '<' || (STR)[2] == '>') \
&& ((STR)[3] == 'X' || (STR)[3] == '0')) ? 4 \
: 0)
#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \
((C) == 'P' ? CONST_OK_FOR_P ((VALUE), (STR)) \
: CONST_OK_FOR_LETTER_P ((VALUE), (C)))
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'I' ? CONST_OK_FOR_I (VALUE) : \
(C) == 'J' ? CONST_OK_FOR_J (VALUE) : \
(C) == 'L' ? CONST_OK_FOR_L (VALUE) : \
(C) == 'M' ? CONST_OK_FOR_M (VALUE) : \
(C) == 'N' ? CONST_OK_FOR_N (VALUE) : \
(C) == 'O' ? CONST_OK_FOR_O (VALUE) : \
0)
/* Similar, but for floating constants, and defining letters G and H.
Here VALUE is the CONST_DOUBLE rtx itself.
`G' is a floating-point zero. */
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'G' ? (VALUE) == CONST0_RTX (SFmode) \
: 0)
/* Return the maximum number of consecutive registers /* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */ needed to represent mode MODE in a register of class CLASS. */
@ -645,122 +575,6 @@ struct cum_arg
#endif #endif
/* Extra constraints. */
#define OK_FOR_Q(OP) \
(TARGET_H8300SX && memory_operand ((OP), VOIDmode))
#define OK_FOR_R(OP) \
(GET_CODE (OP) == CONST_INT \
? !h8300_shift_needs_scratch_p (INTVAL (OP), QImode) \
: 0)
#define OK_FOR_S(OP) \
(GET_CODE (OP) == CONST_INT \
? !h8300_shift_needs_scratch_p (INTVAL (OP), HImode) \
: 0)
#define OK_FOR_T(OP) \
(GET_CODE (OP) == CONST_INT \
? !h8300_shift_needs_scratch_p (INTVAL (OP), SImode) \
: 0)
/* 'U' if valid for a bset destination;
i.e. a register, register indirect, or the eightbit memory region
(a SYMBOL_REF with an SYMBOL_REF_FLAG set).
On the H8S 'U' can also be a 16bit or 32bit absolute. */
#define OK_FOR_U(OP) \
((GET_CODE (OP) == REG && REG_OK_FOR_BASE_P (OP)) \
|| (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
&& REG_OK_FOR_BASE_P (XEXP (OP, 0))) \
|| (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \
&& TARGET_H8300S) \
|| (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == CONST \
&& GET_CODE (XEXP (XEXP (OP, 0), 0)) == PLUS \
&& GET_CODE (XEXP (XEXP (XEXP (OP, 0), 0), 0)) == SYMBOL_REF \
&& GET_CODE (XEXP (XEXP (XEXP (OP, 0), 0), 1)) == CONST_INT \
&& (TARGET_H8300S \
|| SYMBOL_REF_FLAG (XEXP (XEXP (XEXP (OP, 0), 0), 0)))) \
|| (GET_CODE (OP) == MEM \
&& h8300_eightbit_constant_address_p (XEXP (OP, 0))) \
|| (GET_CODE (OP) == MEM && (TARGET_H8300S || TARGET_H8300SX) \
&& GET_CODE (XEXP (OP, 0)) == CONST_INT))
/* Multi-letter constraints starting with W are to be used for
operands that require a memory operand, i.e,. that are never used
along with register constraints (see EXTRA_MEMORY_CONSTRAINTS). */
#define OK_FOR_WU(OP) \
(GET_CODE (OP) == MEM && OK_FOR_U (OP))
#define OK_FOR_W(OP, STR) \
((STR)[1] == 'U' ? OK_FOR_WU (OP) \
: 0)
#define CONSTRAINT_LEN_FOR_W(STR) \
((STR)[1] == 'U' ? 2 \
: 0)
/* Multi-letter constraints starting with Y are to be used for operands
that are constant immediates and have single 1 or 0 in their binary
representation. */
#define OK_FOR_Y2(OP) \
((GET_CODE (OP) == CONST_INT) && (exact_log2 (INTVAL (OP) & 0xff) != -1))
#define OK_FOR_Y0(OP) \
((GET_CODE (OP) == CONST_INT) && (exact_log2 (~INTVAL (OP) & 0xff) != -1))
#define OK_FOR_Y(OP, STR) \
((STR)[1] == '2' ? OK_FOR_Y2 (OP) \
: (STR)[1] == '0' ? OK_FOR_Y0 (OP) \
: 0)
#define CONSTRAINT_LEN_FOR_Y(STR) \
((STR)[1] == '2' ? 2 \
: (STR)[1] == '0' ? 2 \
: 0)
#define OK_FOR_Z(OP) \
(TARGET_H8300SX \
&& GET_CODE (OP) == MEM \
&& CONSTANT_P (XEXP ((OP), 0)))
#define EXTRA_CONSTRAINT_STR(OP, C, STR) \
((C) == 'Q' ? OK_FOR_Q (OP) : \
(C) == 'R' ? OK_FOR_R (OP) : \
(C) == 'S' ? OK_FOR_S (OP) : \
(C) == 'T' ? OK_FOR_T (OP) : \
(C) == 'U' ? OK_FOR_U (OP) : \
(C) == 'W' ? OK_FOR_W ((OP), (STR)) : \
(C) == 'Y' ? OK_FOR_Y ((OP), (STR)) : \
(C) == 'Z' ? OK_FOR_Z (OP) : \
0)
#define CONSTRAINT_LEN(C, STR) \
((C) == 'P' ? CONSTRAINT_LEN_FOR_P (STR) \
: (C) == 'W' ? CONSTRAINT_LEN_FOR_W (STR) \
: (C) == 'Y' ? CONSTRAINT_LEN_FOR_Y (STR) \
: DEFAULT_CONSTRAINT_LEN ((C), (STR)))
/* Experiments suggest that it's better not add 'Q' or 'U' here. No
patterns need it for correctness (no patterns use 'Q' and 'U'
without also providing a register alternative). And defining it
will mean that a spilled pseudo could be replaced by its frame
location in several consecutive insns.
Instead, it seems to be better to force pseudos to be reloaded
into registers and then use peepholes to recombine insns when
beneficial.
Unfortunately, for WU (unlike plain U, that matches regs as well),
we must require a memory address. In fact, all multi-letter
constraints started with W are supposed to have this property, so
we just test for W here. */
#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
((C) == 'W')
/* Specify the machine mode that this machine uses /* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */ for the index in the tablejump instruction. */

View File

@ -177,6 +177,7 @@
(const_int 14)))]) (const_int 14)))])
(include "predicates.md") (include "predicates.md")
(include "constraints.md")
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
;; MOVE INSTRUCTIONS ;; MOVE INSTRUCTIONS
@ -995,7 +996,7 @@
btst\\t%Z1,%Y0 btst\\t%Z1,%Y0
#" #"
"&& reload_completed "&& reload_completed
&& !OK_FOR_U (operands[0])" && !satisfies_constraint_U (operands[0])"
[(set (match_dup 2) [(set (match_dup 2)
(match_dup 0)) (match_dup 0))
(parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2) (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
@ -1065,7 +1066,7 @@
btst\\t%w1,%X0 btst\\t%w1,%X0
#" #"
"&& reload_completed "&& reload_completed
&& !OK_FOR_U (operands[0])" && !satisfies_constraint_U (operands[0])"
[(set (match_dup 2) [(set (match_dup 2)
(match_dup 0)) (match_dup 0))
(parallel [(set (cc0) (compare (zero_extract:SI (zero_extend:SI (match_dup 2)) (parallel [(set (cc0) (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
@ -4867,9 +4868,9 @@
(match_operand:HI 2 "register_operand" "")))] (match_operand:HI 2 "register_operand" "")))]
"REG_P (operands[0]) && REG_P (operands[2]) "REG_P (operands[0]) && REG_P (operands[2])
&& REGNO (operands[0]) != REGNO (operands[2]) && REGNO (operands[0]) != REGNO (operands[2])
&& (CONST_OK_FOR_J (INTVAL (operands[1])) && (satisfies_constraint_J (operands[1])
|| CONST_OK_FOR_L (INTVAL (operands[1])) || satisfies_constraint_L (operands[1])
|| CONST_OK_FOR_N (INTVAL (operands[1])))" || satisfies_constraint_N (operands[1]))"
[(set (match_dup 0) [(set (match_dup 0)
(match_dup 2)) (match_dup 2))
(set (match_dup 0) (set (match_dup 0)
@ -4897,8 +4898,8 @@
"(TARGET_H8300H || TARGET_H8300S) "(TARGET_H8300H || TARGET_H8300S)
&& REG_P (operands[0]) && REG_P (operands[2]) && REG_P (operands[0]) && REG_P (operands[2])
&& REGNO (operands[0]) != REGNO (operands[2]) && REGNO (operands[0]) != REGNO (operands[2])
&& (CONST_OK_FOR_L (INTVAL (operands[1])) && (satisfies_constraint_L (operands[1])
|| CONST_OK_FOR_N (INTVAL (operands[1])))" || satisfies_constraint_N (operands[1]))"
[(set (match_dup 0) [(set (match_dup 0)
(match_dup 2)) (match_dup 2))
(set (match_dup 0) (set (match_dup 0)
@ -4926,8 +4927,8 @@
"(TARGET_H8300H || TARGET_H8300S) "(TARGET_H8300H || TARGET_H8300S)
&& REG_P (operands[0]) && REG_P (operands[1]) && REG_P (operands[0]) && REG_P (operands[1])
&& REGNO (operands[0]) != REGNO (operands[1]) && REGNO (operands[0]) != REGNO (operands[1])
&& !CONST_OK_FOR_L (INTVAL (operands[2])) && !satisfies_constraint_L (operands[2])
&& !CONST_OK_FOR_N (INTVAL (operands[2])) && !satisfies_constraint_N (operands[2])
&& ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2]) && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
|| (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2]) || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
|| INTVAL (operands[2]) == 0xffff || INTVAL (operands[2]) == 0xffff

View File

@ -326,7 +326,7 @@
{ {
/* We can accept any nonimmediate operand, except that MEM operands must /* We can accept any nonimmediate operand, except that MEM operands must
be limited to those that use addresses valid for the 'U' constraint. */ be limited to those that use addresses valid for the 'U' constraint. */
if (!nonimmediate_operand (op, mode) && !OK_FOR_U (op)) if (!nonimmediate_operand (op, mode) && !satisfies_constraint_U (op))
return 0; return 0;
/* H8SX accepts pretty much anything here. */ /* H8SX accepts pretty much anything here. */
@ -344,7 +344,7 @@
if (GET_CODE (op) == SUBREG) if (GET_CODE (op) == SUBREG)
return 1; return 1;
return (GET_CODE (op) == MEM return (GET_CODE (op) == MEM
&& OK_FOR_U (op)); && satisfies_constraint_U (op));
}) })
;; Return nonzero if OP is a MEM suitable for bit manipulation insns. ;; Return nonzero if OP is a MEM suitable for bit manipulation insns.
@ -353,7 +353,7 @@
(match_code "mem") (match_code "mem")
{ {
return (GET_CODE (op) == MEM return (GET_CODE (op) == MEM
&& OK_FOR_U (op)); && satisfies_constraint_U (op));
}) })
;; Return nonzero if OP is indirect register or constant memory ;; Return nonzero if OP is indirect register or constant memory
@ -416,12 +416,9 @@
;; Return nonzero if X is a constant suitable for inc/dec. ;; Return nonzero if X is a constant suitable for inc/dec.
(define_predicate "incdec_operand" (define_predicate "incdec_operand"
(match_code "const_int") (and (match_code "const_int")
{ (ior (match_test "satisfies_constraint_M (op)")
return (GET_CODE (op) == CONST_INT (match_test "satisfies_constraint_O (op)"))))
&& (CONST_OK_FOR_M (INTVAL (op))
|| CONST_OK_FOR_O (INTVAL (op))));
})
;; Recognize valid operators for bit instructions. ;; Recognize valid operators for bit instructions.