common.md: New file.

gcc/
	* common.md: New file.
	* doc/md.texi: Update description of generic, machine-independent
	constraints.
	* config/s390/constraints.md (e): Delete.
	* Makefile.in (md_file): Include common.md.
	* config/m32c/t-m32c (md_file): Likewise.
	* genpreds.c (general_mem): New array.
	(generic_constraint_letters): Remove constraints now defined by
	common.md.
	(add_constraint): Map TARGET_MEM_CONSTRAINT to general_mem.
	Allow the first character to be '<' or '>' as well.
	* genoutput.c (general_mem): New array.
	(indep_constraints): Remove constraints now defined by common.md.
	(note_constraint): Map TARGET_MEM_CONSTRAINT to general_mem.
	Remove special handling of 'm'.
	* ira-costs.c (record_reg_classes): Remove special handling of
	constraints now defined by common.md.
	* ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise.
	* ira-lives.c (single_reg_class): Likewise.
	(ira_implicitly_set_insn_hard_regs): Likewise.
	* lra-constraints.c (reg_class_from_constraints): Likewise.
	(process_alt_operands, process_address, curr_insn_transform): Likewise.
	* postreload.c (reload_cse_simplify_operands): Likewise.
	* reload.c (push_secondary_reload, scratch_reload_class)
	(find_reloads, alternative_allows_const_pool_ref): Likewise.
	* reload1.c (maybe_fix_stack_asms): Likewise.
	* targhooks.c (default_secondary_reload): Likewise.
	* stmt.c (parse_output_constraint): Likewise.
	* recog.c (preprocess_constraints): Likewise.
	(constrain_operands, peep2_find_free_register): Likewise.
	(asm_operand_ok): Likewise, but add a comment saying why 'o'
	must be handled specially.

From-SVN: r211475
This commit is contained in:
Richard Sandiford 2014-06-11 16:59:17 +00:00 committed by Richard Sandiford
parent 7fd308cffa
commit 8677664e02
18 changed files with 209 additions and 697 deletions

View File

@ -1,3 +1,38 @@
2014-06-11 Richard Sandiford <rdsandiford@googlemail.com>
* common.md: New file.
* doc/md.texi: Update description of generic, machine-independent
constraints.
* config/s390/constraints.md (e): Delete.
* Makefile.in (md_file): Include common.md.
* config/m32c/t-m32c (md_file): Likewise.
* genpreds.c (general_mem): New array.
(generic_constraint_letters): Remove constraints now defined by
common.md.
(add_constraint): Map TARGET_MEM_CONSTRAINT to general_mem.
Allow the first character to be '<' or '>' as well.
* genoutput.c (general_mem): New array.
(indep_constraints): Remove constraints now defined by common.md.
(note_constraint): Map TARGET_MEM_CONSTRAINT to general_mem.
Remove special handling of 'm'.
* ira-costs.c (record_reg_classes): Remove special handling of
constraints now defined by common.md.
* ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise.
* ira-lives.c (single_reg_class): Likewise.
(ira_implicitly_set_insn_hard_regs): Likewise.
* lra-constraints.c (reg_class_from_constraints): Likewise.
(process_alt_operands, process_address, curr_insn_transform): Likewise.
* postreload.c (reload_cse_simplify_operands): Likewise.
* reload.c (push_secondary_reload, scratch_reload_class)
(find_reloads, alternative_allows_const_pool_ref): Likewise.
* reload1.c (maybe_fix_stack_asms): Likewise.
* targhooks.c (default_secondary_reload): Likewise.
* stmt.c (parse_output_constraint): Likewise.
* recog.c (preprocess_constraints): Likewise.
(constrain_operands, peep2_find_free_register): Likewise.
(asm_operand_ok): Likewise, but add a comment saying why 'o'
must be handled specially.
2014-06-11 Richard Sandiford <rdsandiford@googlemail.com>
* system.h (CONST_DOUBLE_OK_FOR_CONSTRAINT_P): Poison.

View File

@ -491,7 +491,7 @@ out_file=$(srcdir)/config/@out_file@
out_object_file=@out_object_file@
common_out_file=$(srcdir)/common/config/@common_out_file@
common_out_object_file=@common_out_object_file@
md_file=$(srcdir)/config/@md_file@
md_file=$(srcdir)/common.md $(srcdir)/config/@md_file@
tm_file_list=@tm_file_list@
tm_include_list=@tm_include_list@
tm_defines=@tm_defines@

95
gcc/common.md Normal file
View File

@ -0,0 +1,95 @@
;; Common GCC machine description file, shared by all targets.
;; Copyright (C) 2014 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/>. */
(define_register_constraint "r" "GENERAL_REGS"
"Matches any general register.")
(define_memory_constraint "TARGET_MEM_CONSTRAINT"
"Matches any valid memory."
(and (match_code "mem")
(match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0),
MEM_ADDR_SPACE (op))")))
(define_memory_constraint "o"
"Matches an offsettable memory reference."
(and (match_code "mem")
(match_test "offsettable_nonstrict_memref_p (op)")))
;; "V" matches TARGET_MEM_CONSTRAINTs that are rejected by "o".
;; This means that it is not a memory constraint in the usual sense,
;; since reloading the address into a base register would make the
;; address offsettable.
(define_constraint "V"
"Matches a non-offsettable memory reference."
(and (match_code "mem")
(match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0),
MEM_ADDR_SPACE (op))")
(not (match_test "offsettable_nonstrict_memref_p (op)"))))
;; Like "V", this is not a memory constraint, since reloading the address
;; into a base register would cause it not to match.
(define_constraint "<"
"Matches a pre-dec or post-dec operand."
(and (match_code "mem")
(ior (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")
(match_test "GET_CODE (XEXP (op, 0)) == POST_DEC"))))
;; See the comment for "<".
(define_constraint ">"
"Matches a pre-inc or post-inc operand."
(and (match_code "mem")
(ior (match_test "GET_CODE (XEXP (op, 0)) == PRE_INC")
(match_test "GET_CODE (XEXP (op, 0)) == POST_INC"))))
(define_address_constraint "p"
"Matches a general address."
(match_test "address_operand (op, VOIDmode)"))
(define_constraint "i"
"Matches a general integer constant."
(and (match_test "CONSTANT_P (op)")
(match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)")))
(define_constraint "s"
"Matches a symbolic integer constant."
(and (match_test "CONSTANT_P (op)")
(match_test "!CONST_SCALAR_INT_P (op)")
(match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)")))
(define_constraint "n"
"Matches a non-symbolic integer constant."
(and (match_test "CONST_SCALAR_INT_P (op)")
(match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)")))
(define_constraint "E"
"Matches a floating-point constant."
(ior (match_test "CONST_DOUBLE_AS_FLOAT_P (op)")
(match_test "GET_CODE (op) == CONST_VECTOR
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT")))
;; There is no longer a distinction between "E" and "F".
(define_constraint "F"
"Matches a floating-point constant."
(ior (match_test "CONST_DOUBLE_AS_FLOAT_P (op)")
(match_test "GET_CODE (op) == CONST_VECTOR
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT")))
(define_constraint "X"
"Matches anything."
(match_test "true"))

View File

@ -20,7 +20,7 @@
# target-specific files
md_file = md
md_file = $(srcdir)/common.md md
MD_FILES = m32c constraints predicates addsub bitops blkmov cond jump minmax mov muldiv prologue shift

View File

@ -406,14 +406,6 @@
&& s390_check_symref_alignment (XEXP (op, 0),
GET_MODE_SIZE (GET_MODE (op)))"))
(define_memory_constraint "e"
"Matches all memory references available on the current architecture
level. This constraint will never be used and using it in an inline
assembly is *always* a bug since there is no instruction accepting all
those addresses. It just serves as a placeholder for a generic memory
constraint."
(match_test "strict_memory_address_p (GET_MODE (op), op)"))
; This defines 'm' as normal memory constraint. This is only possible
; since the standard memory constraint is re-defined in s390.h using
; the TARGET_MEM_CONSTRAINT macro.

View File

@ -4355,16 +4355,8 @@ Use this for constraints that should not appear in @code{asm} statements.
It is occasionally useful to test a constraint from C code rather than
implicitly via the constraint string in a @code{match_operand}. The
generated file @file{tm_p.h} declares a few interfaces for working
with machine-specific constraints. None of these interfaces work with
the generic constraints described in @ref{Simple Constraints}. This
may change in the future.
@strong{Warning:} @file{tm_p.h} may declare other functions that
operate on constraints, besides the ones documented here. Do not use
those functions from machine-dependent code. They exist to implement
the old constraint interface that machine-independent components of
the compiler still expect. They will change or disappear in the
future.
with constraints. At present these are defined for all constraints
except @code{g} (which is equivalent to @code{general_operand}).
Some valid constraint names are not valid C identifiers, so there is a
mangling scheme for referring to them from C@. Constraint names that
@ -4391,17 +4383,14 @@ the variable @var{m} is a mangled constraint name (usually as part of
a larger identifier).
@deftp Enum constraint_num
For each machine-specific constraint, there is a corresponding
For each constraint except @code{g}, there is a corresponding
enumeration constant: @samp{CONSTRAINT_} plus the mangled name of the
constraint. Functions that take an @code{enum constraint_num} as an
argument expect one of these constants.
Machine-independent constraints do not have associated constants.
This may change in the future.
@end deftp
@deftypefun {inline bool} satisfies_constraint_@var{m} (rtx @var{exp})
For each machine-specific, non-register constraint @var{m}, there is
For each non-register constraint @var{m} except @code{g}, there is
one of these functions; it returns @code{true} if @var{exp} satisfies the
constraint. These functions are only visible if @file{rtl.h} was included
before @file{tm_p.h}.

View File

@ -98,6 +98,8 @@ along with GCC; see the file COPYING3. If not see
#define MAX_MAX_OPERANDS 40
static char general_mem[] = { TARGET_MEM_CONSTRAINT, 0 };
static int n_occurrences (int, const char *);
static const char *strip_whitespace (const char *);
@ -205,10 +207,9 @@ struct constraint_data
const char name[1];
};
/* This is a complete list (unlike the one in genpreds.c) of constraint
letters and modifiers with machine-independent meaning. The only
omission is digits, as these are handled specially. */
static const char indep_constraints[] = ",=+%*?!#&<>EFVXgimnoprs";
/* All machine-independent constraint characters (except digits) that
are handled outside the define*_constraint mechanism. */
static const char indep_constraints[] = ",=+%*?!#&g";
static struct constraint_data *
constraints_by_letter_table[1 << CHAR_BIT];
@ -1151,13 +1152,13 @@ static void
note_constraint (rtx exp, int lineno)
{
const char *name = XSTR (exp, 0);
unsigned int namelen = strlen (name);
struct constraint_data **iter, **slot, *new_cdata;
/* The 'm' constraint is special here since that constraint letter
can be overridden by the back end by defining the
TARGET_MEM_CONSTRAINT macro. */
if (strchr (indep_constraints, name[0]) && name[0] != 'm')
if (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0)
name = general_mem;
unsigned int namelen = strlen (name);
if (strchr (indep_constraints, name[0]))
{
if (name[1] == '\0')
error_with_line (lineno, "constraint letter '%s' cannot be "

View File

@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see
#include "read-md.h"
#include "gensupport.h"
static char general_mem[] = { TARGET_MEM_CONSTRAINT, 0 };
/* Given a predicate expression EXP, from form NAME at line LINENO,
verify that it does not contain any RTL constructs which are not
valid in predicate definitions. Returns true if EXP is
@ -659,12 +661,9 @@ static struct constraint_data **last_constraint_ptr = &first_constraint;
#define FOR_ALL_CONSTRAINTS(iter_) \
for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual)
/* These letters, and all names beginning with them, are reserved for
generic constraints.
The 'm' constraint is not mentioned here since that constraint
letter can be overridden by the back end by defining the
TARGET_MEM_CONSTRAINT macro. */
static const char generic_constraint_letters[] = "EFVXginoprs";
/* Contraint letters that have a special meaning and that cannot be used
in define*_constraints. */
static const char generic_constraint_letters[] = "g";
/* Machine-independent code expects that constraints with these
(initial) letters will allow only (a subset of all) CONST_INTs. */
@ -735,19 +734,12 @@ add_constraint (const char *name, const char *regclass,
bool is_const_dbl;
size_t namelen;
if (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0)
name = general_mem;
if (exp && validate_exp (exp, name, lineno))
return;
if (!ISALPHA (name[0]) && name[0] != '_')
{
if (name[1] == '\0')
error_with_line (lineno, "constraint name '%s' is not "
"a letter or underscore", name);
else
error_with_line (lineno, "constraint name '%s' does not begin "
"with a letter or underscore", name);
return;
}
for (p = name; *p; p++)
if (!ISALNUM (*p))
{

View File

@ -645,8 +645,6 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
{
switch (c)
{
case ',':
break;
case '*':
/* Ignore the next letter for this pass. */
c = *++p;
@ -654,72 +652,6 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
case '?':
alt_cost += 2;
case '!': case '#': case '&':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
break;
case 'p':
allows_addr = 1;
win = address_operand (op, GET_MODE (op));
/* We know this operand is an address, so we want it
to be allocated to a register that can be the
base of an address, i.e. BASE_REG_CLASS. */
classes[i]
= ira_reg_class_subunion[classes[i]]
[base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH)];
break;
case 'm': case 'o': case 'V':
/* It doesn't seem worth distinguishing between
offsettable and non-offsettable addresses
here. */
insn_allows_mem[i] = allows_mem[i] = 1;
if (MEM_P (op))
win = 1;
break;
case '<':
if (MEM_P (op)
&& (GET_CODE (XEXP (op, 0)) == PRE_DEC
|| GET_CODE (XEXP (op, 0)) == POST_DEC))
win = 1;
break;
case '>':
if (MEM_P (op)
&& (GET_CODE (XEXP (op, 0)) == PRE_INC
|| GET_CODE (XEXP (op, 0)) == POST_INC))
win = 1;
break;
case 'E':
case 'F':
if (CONST_DOUBLE_AS_FLOAT_P (op)
|| (GET_CODE (op) == CONST_VECTOR
&& (GET_MODE_CLASS (GET_MODE (op))
== MODE_VECTOR_FLOAT)))
win = 1;
break;
case 's':
if (CONST_SCALAR_INT_P (op))
break;
case 'i':
if (CONSTANT_P (op)
&& (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)))
win = 1;
break;
case 'n':
if (CONST_SCALAR_INT_P (op))
win = 1;
break;
case 'X':
win = 1;
break;
case 'g':
@ -728,7 +660,6 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
&& (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))))
win = 1;
insn_allows_mem[i] = allows_mem[i] = 1;
case 'r':
classes[i] = ira_reg_class_subunion[classes[i]][GENERAL_REGS];
break;

View File

@ -771,60 +771,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
else if (enabled & 1)
switch (c)
{
case ' ':
case '\t':
case '=':
case '+':
case '*':
case '&':
case '%':
case '!':
case '?':
break;
case 'i':
if (CONSTANT_P (op)
|| (equiv_const != NULL_RTX && CONSTANT_P (equiv_const)))
return NO_REGS;
break;
case 'g':
return NO_REGS;
case 'n':
if (CONST_SCALAR_INT_P (op)
|| (equiv_const != NULL_RTX && CONST_SCALAR_INT_P (equiv_const)))
return NO_REGS;
break;
case 's':
if ((CONSTANT_P (op) && !CONST_SCALAR_INT_P (op))
|| (equiv_const != NULL_RTX
&& CONSTANT_P (equiv_const)
&& !CONST_SCALAR_INT_P (equiv_const)))
return NO_REGS;
break;
case 'E':
case 'F':
if (CONST_DOUBLE_AS_FLOAT_P (op)
|| (GET_CODE (op) == CONST_VECTOR
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT)
|| (equiv_const != NULL_RTX
&& (CONST_DOUBLE_AS_FLOAT_P (equiv_const)
|| (GET_CODE (equiv_const) == CONST_VECTOR
&& (GET_MODE_CLASS (GET_MODE (equiv_const))
== MODE_VECTOR_FLOAT)))))
return NO_REGS;
break;
case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
case 'O': case 'P':
case 'G': case 'H':
case 'r':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'h': case 'j': case 'k': case 'l':
case 'q': case 't': case 'u':
case 'v': case 'w': case 'x': case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D':
case 'Q': case 'R': case 'S': case 'T': case 'U':
case 'W': case 'Y': case 'Z':
default:
/* ??? Is this the best way to handle memory constraints? */
cn = lookup_constraint (constraints);
if (insn_extra_memory_constraint (cn)
@ -835,9 +785,7 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
&& CONSTANT_P (equiv_const)
&& constraint_satisfied_p (equiv_const, cn)))
return NO_REGS;
next_cl = (c == 'r'
? GENERAL_REGS
: reg_class_for_constraint (cn));
next_cl = reg_class_for_constraint (cn);
if (next_cl == NO_REGS)
break;
if (cl == NO_REGS
@ -860,9 +808,6 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
return NO_REGS;
cl = next_cl;
break;
default:
return NO_REGS;
}
return cl;
}
@ -913,29 +858,17 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set)
else if (c == ',')
enabled >>= 1;
else if (enabled & 1)
switch (c)
{
case 'r':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'h': case 'j': case 'k': case 'l':
case 'q': case 't': case 'u':
case 'v': case 'w': case 'x': case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D':
case 'Q': case 'R': case 'S': case 'T': case 'U':
case 'W': case 'Y': case 'Z':
cl = (c == 'r'
? GENERAL_REGS
: reg_class_for_constraint (lookup_constraint (p)));
if (cl != NO_REGS)
{
/* There is no register pressure problem if all of the
regs in this class are fixed. */
int regno = ira_class_singleton[cl][mode];
if (regno >= 0)
add_to_hard_reg_set (set, mode, regno);
}
break;
}
{
cl = reg_class_for_constraint (lookup_constraint (p));
if (cl != NO_REGS)
{
/* There is no register pressure problem if all of the
regs in this class are fixed. */
int regno = ira_class_singleton[cl][mode];
if (regno >= 0)
add_to_hard_reg_set (set, mode, regno);
}
}
}
}
}

View File

@ -1835,9 +1835,6 @@ ira_setup_alts (rtx insn, HARD_REG_SET &alts)
len = 0;
break;
case '?': case '!': case '*': case '=': case '+':
break;
case '%':
/* We only support one commutative marker, the
first one. We already set commutative
@ -1846,63 +1843,12 @@ ira_setup_alts (rtx insn, HARD_REG_SET &alts)
commutative = nop;
break;
case '&':
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
goto op_success;
break;
case 'p':
case 'g':
case 'X':
case TARGET_MEM_CONSTRAINT:
goto op_success;
break;
case '<':
if (MEM_P (op)
&& (GET_CODE (XEXP (op, 0)) == PRE_DEC
|| GET_CODE (XEXP (op, 0)) == POST_DEC))
goto op_success;
break;
case '>':
if (MEM_P (op)
&& (GET_CODE (XEXP (op, 0)) == PRE_INC
|| GET_CODE (XEXP (op, 0)) == POST_INC))
goto op_success;
break;
case 'E':
case 'F':
if (CONST_DOUBLE_AS_FLOAT_P (op)
|| (GET_CODE (op) == CONST_VECTOR
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT))
goto op_success;
break;
case 's':
if (CONST_SCALAR_INT_P (op))
break;
case 'i':
if (CONSTANT_P (op))
goto op_success;
break;
case 'n':
if (CONST_SCALAR_INT_P (op))
goto op_success;
break;
case 'V':
if (MEM_P (op) && ! offsettable_memref_p (op))
goto op_success;
break;
case 'o':
case 'r':
goto op_success;
break;
@ -1992,21 +1938,9 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts)
else if (! ignore_p)
switch (c)
{
case 'X':
case 'p':
case 'g':
goto fail;
case 'r':
if (!targetm.class_likely_spilled_p (GENERAL_REGS))
goto fail;
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'h': case 'j': case 'k': case 'l':
case 'q': case 't': case 'u':
case 'v': case 'w': case 'x': case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D':
case 'Q': case 'R': case 'S': case 'T': case 'U':
case 'W': case 'Y': case 'Z':
default:
{
enum constraint_num cn = lookup_constraint (str);
enum reg_class cl = reg_class_for_constraint (cn);

View File

@ -968,14 +968,7 @@ reg_class_from_constraints (const char *p)
case ',':
return op_class;
case 'p':
op_class = (reg_class_subunion
[op_class][base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH)]);
break;
case 'g':
case 'r':
op_class = reg_class_subunion[op_class][GENERAL_REGS];
break;
@ -1768,15 +1761,6 @@ process_alt_operands (int only_alternative)
c = '\0';
break;
case '=': case '+': case '?': case '*': case '!':
case ' ': case '\t':
break;
case '%':
/* We only support one commutative marker, the first
one. We already set commutative above. */
break;
case '&':
early_clobber_p = true;
break;
@ -1909,105 +1893,11 @@ process_alt_operands (int only_alternative)
break;
}
case 'p':
cl = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH);
this_alternative = reg_class_subunion[this_alternative][cl];
IOR_HARD_REG_SET (this_alternative_set,
reg_class_contents[cl]);
if (costly_p)
{
this_costly_alternative
= reg_class_subunion[this_costly_alternative][cl];
IOR_HARD_REG_SET (this_costly_alternative_set,
reg_class_contents[cl]);
}
win = true;
badop = false;
break;
case TARGET_MEM_CONSTRAINT:
if (MEM_P (op) || spilled_pseudo_p (op))
win = true;
/* We can put constant or pseudo value into memory
to satisfy the constraint. */
if (CONST_POOL_OK_P (mode, op) || REG_P (op))
badop = false;
constmemok = true;
break;
case '<':
if (MEM_P (op)
&& (GET_CODE (XEXP (op, 0)) == PRE_DEC
|| GET_CODE (XEXP (op, 0)) == POST_DEC))
win = true;
break;
case '>':
if (MEM_P (op)
&& (GET_CODE (XEXP (op, 0)) == PRE_INC
|| GET_CODE (XEXP (op, 0)) == POST_INC))
win = true;
break;
/* Memory op whose address is not offsettable. */
case 'V':
if (MEM_P (op)
&& ! offsettable_nonstrict_memref_p (op))
win = true;
break;
/* Memory operand whose address is offsettable. */
case 'o':
if ((MEM_P (op)
&& offsettable_nonstrict_memref_p (op))
|| spilled_pseudo_p (op))
win = true;
/* We can put constant or pseudo value into memory
or make memory address offsetable to satisfy the
constraint. */
if (CONST_POOL_OK_P (mode, op) || MEM_P (op) || REG_P (op))
badop = false;
constmemok = true;
offmemok = true;
break;
case 'E':
case 'F':
if (GET_CODE (op) == CONST_DOUBLE
|| (GET_CODE (op) == CONST_VECTOR
&& (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)))
win = true;
break;
case 's':
if (CONST_SCALAR_INT_P (op))
break;
case 'i':
if (general_constant_p (op))
win = true;
break;
case 'n':
if (CONST_SCALAR_INT_P (op))
win = true;
break;
case 'X':
/* This constraint should be excluded by the fast
track. */
gcc_unreachable ();
break;
case 'g':
if (MEM_P (op)
|| general_constant_p (op)
|| spilled_pseudo_p (op))
win = true;
/* Drop through into 'r' case. */
case 'r':
cl = GENERAL_REGS;
goto reg;
@ -2821,8 +2711,7 @@ process_address_1 (int nop, rtx *before, rtx *after)
enum constraint_num cn = lookup_constraint (constraint);
bool change_p;
if (constraint[0] == 'p'
|| insn_extra_address_constraint (cn))
if (insn_extra_address_constraint (cn))
decompose_lea_address (&ad, curr_id->operand_loc[nop]);
else if (MEM_P (op))
decompose_mem_address (&ad, op);
@ -2853,8 +2742,7 @@ process_address_1 (int nop, rtx *before, rtx *after)
/* Target hooks sometimes don't treat extra-constraint addresses as
legitimate address_operands, so handle them specially. */
if (constraint[0] != 'p'
&& insn_extra_address_constraint (cn)
if (insn_extra_address_constraint (cn)
&& satisfies_address_constraint_p (&ad, cn))
return change_p;
@ -3576,8 +3464,6 @@ curr_insn_transform (void)
(c = *constraint) && c != ',' && c != '#';
constraint += CONSTRAINT_LEN (c, constraint))
{
if (c == TARGET_MEM_CONSTRAINT || c == 'o')
break;
enum constraint_num cn = lookup_constraint (constraint);
if (insn_extra_memory_constraint (cn)
&& satisfies_memory_constraint_p (tem, cn))

View File

@ -553,22 +553,8 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
switch (c)
{
case '=': case '+': case '?':
case '#': case '&': case '!':
case '*': case '%':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '<': case '>': case 'V': case 'o':
case 'E': case 'F': case 'G': case 'H':
case 's': case 'i': case 'n':
case 'I': case 'J': case 'K': case 'L':
case 'M': case 'N': case 'O': case 'P':
case 'p': case 'X': case TARGET_MEM_CONSTRAINT:
/* These don't say anything we care about. */
break;
case 'g': case 'r':
rclass = reg_class_subunion[(int) rclass][(int) GENERAL_REGS];
case 'g':
rclass = reg_class_subunion[rclass][GENERAL_REGS];
break;
default:

View File

@ -1737,15 +1737,6 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
case ',':
constraint++;
continue;
case '=':
case '+':
case '*':
case '%':
case '!':
case '#':
case '&':
case '?':
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
@ -1774,98 +1765,47 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
}
continue;
case 'p':
if (address_operand (op, VOIDmode))
result = 1;
break;
case TARGET_MEM_CONSTRAINT:
case 'V': /* non-offsettable */
if (memory_operand (op, VOIDmode))
result = 1;
break;
/* The rest of the compiler assumes that reloading the address
of a MEM into a register will make it fit an 'o' constraint.
That is, if it sees a MEM operand for an 'o' constraint,
it assumes that (mem (base-reg)) will fit.
That assumption fails on targets that don't have offsettable
addresses at all. We therefore need to treat 'o' asm
constraints as a special case and only accept operands that
are already offsettable, thus proving that at least one
offsettable address exists. */
case 'o': /* offsettable */
if (offsettable_nonstrict_memref_p (op))
result = 1;
break;
case '<':
/* ??? Before auto-inc-dec, auto inc/dec insns are not supposed to exist,
excepting those that expand_call created. Further, on some
machines which do not have generalized auto inc/dec, an inc/dec
is not a memory_operand.
Match any memory and hope things are resolved after reload. */
if (MEM_P (op)
&& (1
|| GET_CODE (XEXP (op, 0)) == PRE_DEC
|| GET_CODE (XEXP (op, 0)) == POST_DEC))
result = 1;
#ifdef AUTO_INC_DEC
incdec_ok = true;
#endif
break;
case '>':
if (MEM_P (op)
&& (1
|| GET_CODE (XEXP (op, 0)) == PRE_INC
|| GET_CODE (XEXP (op, 0)) == POST_INC))
result = 1;
#ifdef AUTO_INC_DEC
incdec_ok = true;
#endif
break;
case 'E':
case 'F':
if (CONST_DOUBLE_AS_FLOAT_P (op)
|| (GET_CODE (op) == CONST_VECTOR
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT))
result = 1;
break;
case 's':
if (CONST_SCALAR_INT_P (op))
break;
/* Fall through. */
case 'i':
if (CONSTANT_P (op) && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)))
result = 1;
break;
case 'n':
if (CONST_SCALAR_INT_P (op))
result = 1;
break;
case 'X':
result = 1;
break;
case 'g':
if (general_operand (op, VOIDmode))
result = 1;
break;
case 'r':
reg:
if (!result
&& GET_MODE (op) != BLKmode
&& register_operand (op, VOIDmode))
result = 1;
break;
#ifdef AUTO_INC_DEC
case '<':
case '>':
/* ??? Before auto-inc-dec, auto inc/dec insns are not supposed
to exist, excepting those that expand_call created. Further,
on some machines which do not have generalized auto inc/dec,
an inc/dec is not a memory_operand.
Match any memory and hope things are resolved after reload. */
incdec_ok = true;
#endif
default:
cn = lookup_constraint (constraint);
switch (get_constraint_type (cn))
{
case CT_REGISTER:
if (reg_class_for_constraint (cn) != NO_REGS)
goto reg;
if (!result
&& reg_class_for_constraint (cn) != NO_REGS
&& GET_MODE (op) != BLKmode
&& register_operand (op, VOIDmode))
result = 1;
break;
case CT_CONST_INT:
@ -2339,14 +2279,6 @@ preprocess_constraints (int n_operands, int n_alternatives,
switch (c)
{
case '=': case '+': case '*': case '%':
case 'E': case 'F': case 'G': case 'H':
case 's': case 'i': case 'n':
case 'I': case 'J': case 'K': case 'L':
case 'M': case 'N': case 'O': case 'P':
/* These don't say anything we care about. */
break;
case '?':
op_alt[i].reject += 6;
break;
@ -2367,22 +2299,11 @@ preprocess_constraints (int n_operands, int n_alternatives,
}
continue;
case TARGET_MEM_CONSTRAINT:
op_alt[i].memory_ok = 1;
break;
case 'X':
op_alt[i].anything_ok = 1;
break;
case 'p':
op_alt[i].is_address = 1;
op_alt[i].cl = reg_class_subunion[(int) op_alt[i].cl]
[(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH)];
break;
case 'g':
case 'r':
op_alt[i].cl =
reg_class_subunion[(int) op_alt[i].cl][(int) GENERAL_REGS];
break;
@ -2592,10 +2513,6 @@ constrain_operands (int strict)
c = '\0';
break;
case '?': case '!': case '*': case '%':
case '=': case '+':
break;
case '#':
/* Ignore rest of this alternative as far as
constraint checking is concerned. */
@ -2695,106 +2612,10 @@ constrain_operands (int strict)
win = 1;
break;
case 'X':
/* This is used for a MATCH_SCRATCH in the cases when
we don't actually need anything. So anything goes
any time. */
win = 1;
break;
case TARGET_MEM_CONSTRAINT:
/* Memory operands must be valid, to the extent
required by STRICT. */
if (MEM_P (op))
{
if (strict > 0
&& !strict_memory_address_addr_space_p
(GET_MODE (op), XEXP (op, 0),
MEM_ADDR_SPACE (op)))
break;
if (strict == 0
&& !memory_address_addr_space_p
(GET_MODE (op), XEXP (op, 0),
MEM_ADDR_SPACE (op)))
break;
win = 1;
}
/* Before reload, accept what reload can turn into mem. */
else if (strict < 0 && CONSTANT_P (op))
win = 1;
/* During reload, accept a pseudo */
else if (reload_in_progress && REG_P (op)
&& REGNO (op) >= FIRST_PSEUDO_REGISTER)
win = 1;
break;
case '<':
if (MEM_P (op)
&& (GET_CODE (XEXP (op, 0)) == PRE_DEC
|| GET_CODE (XEXP (op, 0)) == POST_DEC))
win = 1;
break;
case '>':
if (MEM_P (op)
&& (GET_CODE (XEXP (op, 0)) == PRE_INC
|| GET_CODE (XEXP (op, 0)) == POST_INC))
win = 1;
break;
case 'E':
case 'F':
if (CONST_DOUBLE_AS_FLOAT_P (op)
|| (GET_CODE (op) == CONST_VECTOR
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT))
win = 1;
break;
case 's':
if (CONST_SCALAR_INT_P (op))
break;
case 'i':
if (CONSTANT_P (op))
win = 1;
break;
case 'n':
if (CONST_SCALAR_INT_P (op))
win = 1;
break;
case 'V':
if (MEM_P (op)
&& ((strict > 0 && ! offsettable_memref_p (op))
|| (strict < 0
&& !(CONSTANT_P (op) || MEM_P (op)))
|| (reload_in_progress
&& !(REG_P (op)
&& REGNO (op) >= FIRST_PSEUDO_REGISTER))))
win = 1;
break;
case 'o':
if ((strict > 0 && offsettable_memref_p (op))
|| (strict == 0 && offsettable_nonstrict_memref_p (op))
/* Before reload, accept what reload can handle. */
|| (strict < 0
&& (CONSTANT_P (op) || MEM_P (op)))
/* During reload, accept a pseudo */
|| (reload_in_progress && REG_P (op)
&& REGNO (op) >= FIRST_PSEUDO_REGISTER))
win = 1;
break;
default:
{
enum reg_class cl;
enum constraint_num cn = (c == 'r'
? CONSTRAINT__UNKNOWN
: lookup_constraint (p));
cl = (c == 'r'
? GENERAL_REGS : reg_class_for_constraint (cn));
enum constraint_num cn = lookup_constraint (p);
enum reg_class cl = reg_class_for_constraint (cn);
if (cl != NO_REGS)
{
if (strict < 0
@ -3227,8 +3048,7 @@ peep2_find_free_register (int from, int to, const char *class_str,
from = peep2_buf_position (from + 1);
}
cl = (class_str[0] == 'r' ? GENERAL_REGS
: reg_class_for_constraint (lookup_constraint (class_str)));
cl = reg_class_for_constraint (lookup_constraint (class_str));
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{

View File

@ -328,7 +328,6 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
enum reload_type secondary_type;
int s_reload, t_reload = -1;
const char *scratch_constraint;
char letter;
secondary_reload_info sri;
if (type == RELOAD_FOR_INPUT_ADDRESS
@ -399,10 +398,8 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
scratch_constraint++;
if (*scratch_constraint == '&')
scratch_constraint++;
letter = *scratch_constraint;
scratch_class = (letter == 'r' ? GENERAL_REGS
: (reg_class_for_constraint
(lookup_constraint (scratch_constraint))));
scratch_class = (reg_class_for_constraint
(lookup_constraint (scratch_constraint)));
rclass = scratch_class;
mode = insn_data[(int) icode].operand[2].mode;
@ -548,7 +545,6 @@ enum reg_class
scratch_reload_class (enum insn_code icode)
{
const char *scratch_constraint;
char scratch_letter;
enum reg_class rclass;
gcc_assert (insn_data[(int) icode].n_operands == 3);
@ -557,9 +553,6 @@ scratch_reload_class (enum insn_code icode)
scratch_constraint++;
if (*scratch_constraint == '&')
scratch_constraint++;
scratch_letter = *scratch_constraint;
if (scratch_letter == 'r')
return GENERAL_REGS;
rclass = reg_class_for_constraint (lookup_constraint (scratch_constraint));
gcc_assert (rclass != NO_REGS);
return rclass;
@ -2850,9 +2843,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
if (*constraints[i] == 0)
/* Ignore things like match_operator operands. */
;
else if (constraints[i][0] == 'p'
|| (insn_extra_address_constraint
(lookup_constraint (constraints[i]))))
else if (insn_extra_address_constraint
(lookup_constraint (constraints[i])))
{
address_operand_reloaded[i]
= find_reloads_address (recog_data.operand_mode[i], (rtx*) 0,
@ -3209,14 +3201,6 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
c = '\0';
break;
case '=': case '+': case '*':
break;
case '%':
/* We only support one commutative marker, the first
one. We already set commutative above. */
break;
case '?':
reject += 6;
break;
@ -3425,29 +3409,6 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
earlyclobber = 1, this_earlyclobber = 1;
break;
case 'E':
case 'F':
if (CONST_DOUBLE_AS_FLOAT_P (operand)
|| (GET_CODE (operand) == CONST_VECTOR
&& (GET_MODE_CLASS (GET_MODE (operand))
== MODE_VECTOR_FLOAT)))
win = 1;
break;
case 's':
if (CONST_SCALAR_INT_P (operand))
break;
case 'i':
if (CONSTANT_P (operand)
&& (! flag_pic || LEGITIMATE_PIC_OPERAND_P (operand)))
win = 1;
break;
case 'n':
if (CONST_SCALAR_INT_P (operand))
win = 1;
break;
case 'X':
force_reload = 0;
win = 1;
@ -3468,9 +3429,6 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
|| (REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0)))
win = 1;
/* Drop through into 'r' case. */
case 'r':
cl = GENERAL_REGS;
goto reg;
@ -4677,8 +4635,6 @@ alternative_allows_const_pool_ref (rtx mem ATTRIBUTE_UNUSED,
for (; (c = *constraint) && c != ',' && c != '#';
constraint += CONSTRAINT_LEN (c, constraint))
{
if (c == TARGET_MEM_CONSTRAINT || c == 'o')
return true;
enum constraint_num cn = lookup_constraint (constraint);
if (insn_extra_memory_constraint (cn)
&& (mem == NULL || constraint_satisfied_p (mem, cn)))

View File

@ -1417,22 +1417,7 @@ maybe_fix_stack_asms (void)
switch (c)
{
case '=': case '+': case '*': case '%': case '?': case '!':
case '0': case '1': case '2': case '3': case '4': case '<':
case '>': case 'V': case 'o': case '&': case 'E': case 'F':
case 's': case 'i': case 'n': case 'X': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
case TARGET_MEM_CONSTRAINT:
break;
case 'p':
cls = (int) reg_class_subunion[cls]
[(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH)];
break;
case 'g':
case 'r':
cls = (int) reg_class_subunion[cls][(int) GENERAL_REGS];
break;

View File

@ -286,10 +286,6 @@ parse_output_constraint (const char **constraint_p, int operand_num,
}
break;
case 'V': case TARGET_MEM_CONSTRAINT: case 'o':
*allows_mem = true;
break;
case '?': case '!': case '*': case '&': case '#':
case 'E': case 'F': case 'G': case 'H':
case 's': case 'i': case 'n':
@ -315,10 +311,6 @@ parse_output_constraint (const char **constraint_p, int operand_num,
*allows_mem = true;
break;
case 'p': case 'r':
*allows_reg = true;
break;
default:
if (!ISALPHA (*p))
break;
@ -383,10 +375,6 @@ parse_input_constraint (const char **constraint_p, int input_num,
}
break;
case 'V': case TARGET_MEM_CONSTRAINT: case 'o':
*allows_mem = true;
break;
case '<': case '>':
case '?': case '!': case '*': case '#':
case 'E': case 'F': case 'G': case 'H':
@ -437,10 +425,6 @@ parse_input_constraint (const char **constraint_p, int input_num,
}
/* Fall through. */
case 'p': case 'r':
*allows_reg = true;
break;
case 'g': case 'X':
*allows_reg = true;
*allows_mem = true;

View File

@ -919,7 +919,6 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
else if (icode != CODE_FOR_nothing)
{
const char *insn_constraint, *scratch_constraint;
char insn_letter, scratch_letter;
enum reg_class insn_class, scratch_class;
gcc_assert (insn_data[(int) icode].n_operands == 3);
@ -933,11 +932,8 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
gcc_assert (*insn_constraint == '=');
insn_constraint++;
}
insn_letter = *insn_constraint;
insn_class
= (insn_letter == 'r' ? GENERAL_REGS
: (reg_class_for_constraint
(lookup_constraint (insn_constraint))));
insn_class = (reg_class_for_constraint
(lookup_constraint (insn_constraint)));
gcc_assert (insn_class != NO_REGS);
}
@ -951,11 +947,8 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
scratch_constraint++;
if (*scratch_constraint == '&')
scratch_constraint++;
scratch_letter = *scratch_constraint;
scratch_class
= (scratch_letter == 'r' ? GENERAL_REGS
: (reg_class_for_constraint
(lookup_constraint (scratch_constraint))));
scratch_class = (reg_class_for_constraint
(lookup_constraint (scratch_constraint)));
if (reg_class_subset_p (reload_class, insn_class))
{