local-alloc.c (requires_inout): Don't use reserved range for EXTRA_CONSTRAINTS...
* local-alloc.c (requires_inout): Don't use reserved range for EXTRA_CONSTRAINTS; use anything not matched by REG_CLASS_FROM_LETTER. * recog.c (asm_operand_ok): Likewise. (preprocess_constraints, constrain_operands): Likewise. * regclass.c (record_reg_classes): Likewise. * reload.c (find_reloads): Likewise. * reload1.c (maybe_fix_stack_asms): Likewise. (reload_cse_simplify_operands): Likewise. * stmt.c (expand_asm_operands): Likewise. * md.texi: Update constraints documentation. * tm.texi (EXTRA_CONSTRAINT): Update. From-SVN: r36023
This commit is contained in:
parent
881c6935bf
commit
c2cba7a96e
|
@ -1,3 +1,18 @@
|
|||
2000-08-28 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* local-alloc.c (requires_inout): Don't use reserved range for
|
||||
EXTRA_CONSTRAINTS; use anything not matched by REG_CLASS_FROM_LETTER.
|
||||
* recog.c (asm_operand_ok): Likewise.
|
||||
(preprocess_constraints, constrain_operands): Likewise.
|
||||
* regclass.c (record_reg_classes): Likewise.
|
||||
* reload.c (find_reloads): Likewise.
|
||||
* reload1.c (maybe_fix_stack_asms): Likewise.
|
||||
(reload_cse_simplify_operands): Likewise.
|
||||
* stmt.c (expand_asm_operands): Likewise.
|
||||
|
||||
* md.texi: Update constraints documentation.
|
||||
* tm.texi (EXTRA_CONSTRAINT): Update.
|
||||
|
||||
2000-08-28 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* dwarf2out.c (new_loc_descr): Use calloc.
|
||||
|
|
|
@ -2210,9 +2210,6 @@ requires_inout (p)
|
|||
case 's': case 'i': case 'n':
|
||||
case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P':
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
case 'Q': case 'R': case 'S': case 'T': case 'U':
|
||||
#endif
|
||||
case 'X':
|
||||
/* These don't say anything we care about. */
|
||||
break;
|
||||
|
@ -2228,9 +2225,12 @@ requires_inout (p)
|
|||
found_zero = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
|
||||
break;
|
||||
/* FALLTHRU */
|
||||
case 'p':
|
||||
case 'g': case 'r':
|
||||
default:
|
||||
reg_allowed = 1;
|
||||
break;
|
||||
}
|
||||
|
|
32
gcc/md.texi
32
gcc/md.texi
|
@ -728,13 +728,6 @@ postincrement) is allowed.
|
|||
A register operand is allowed provided that it is in a general
|
||||
register.
|
||||
|
||||
@cindex @samp{d} in constraint
|
||||
@item @samp{d}, @samp{a}, @samp{f}, @dots{}
|
||||
Other letters can be defined in machine-dependent fashion to stand for
|
||||
particular classes of registers. @samp{d}, @samp{a} and @samp{f} are
|
||||
defined on the 68000/68020 to stand for data, address and floating
|
||||
point registers.
|
||||
|
||||
@cindex constants in constraints
|
||||
@cindex @samp{i} in constraint
|
||||
@item @samp{i}
|
||||
|
@ -866,22 +859,21 @@ as the predicate in the @code{match_operand}. This predicate interprets
|
|||
the mode specified in the @code{match_operand} as the mode of the memory
|
||||
reference for which the address would be valid.
|
||||
|
||||
@cindex other register constraints
|
||||
@cindex extensible constraints
|
||||
@cindex @samp{Q}, in constraint
|
||||
@item @samp{Q}, @samp{R}, @samp{S}, @dots{} @samp{U}
|
||||
Letters in the range @samp{Q} through @samp{U} may be defined in a
|
||||
machine-dependent fashion to stand for arbitrary operand types.
|
||||
@item @var{other letters}
|
||||
Other letters can be defined in machine-dependent fashion to stand for
|
||||
particular classes of registers or other arbitrary operand types.
|
||||
@samp{d}, @samp{a} and @samp{f} are defined on the 68000/68020 to stand
|
||||
for data, address and floating point registers.
|
||||
|
||||
@ifset INTERNALS
|
||||
The machine description macro @code{EXTRA_CONSTRAINT} is passed the
|
||||
operand as its first argument and the constraint letter as its
|
||||
second operand.
|
||||
The machine description macro @code{REG_CLASS_FROM_LETTER} has first
|
||||
cut at the otherwise unused letters. If it evaluates to @code{NO_REGS},
|
||||
then @code{EXTRA_CONSTRAINT} is evaluated.
|
||||
|
||||
A typical use for this would be to distinguish certain types of
|
||||
memory references that affect other insn operands.
|
||||
|
||||
Do not define these constraint letters to accept register references
|
||||
(@code{reg}); the reload pass does not expect this and would not handle
|
||||
it properly.
|
||||
A typical use for @code{EXTRA_CONSTRANT} would be to distinguish certain
|
||||
types of memory references that affect other insn operands.
|
||||
@end ifset
|
||||
@end table
|
||||
|
||||
|
|
101
gcc/recog.c
101
gcc/recog.c
|
@ -1571,7 +1571,8 @@ asm_operand_ok (op, constraint)
|
|||
|
||||
while (*constraint)
|
||||
{
|
||||
switch (*constraint++)
|
||||
char c = *constraint++;
|
||||
switch (c)
|
||||
{
|
||||
case '=':
|
||||
case '+':
|
||||
|
@ -1731,35 +1732,21 @@ asm_operand_ok (op, constraint)
|
|||
return 1;
|
||||
break;
|
||||
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
case 'Q':
|
||||
if (EXTRA_CONSTRAINT (op, 'Q'))
|
||||
return 1;
|
||||
break;
|
||||
case 'R':
|
||||
if (EXTRA_CONSTRAINT (op, 'R'))
|
||||
return 1;
|
||||
break;
|
||||
case 'S':
|
||||
if (EXTRA_CONSTRAINT (op, 'S'))
|
||||
return 1;
|
||||
break;
|
||||
case 'T':
|
||||
if (EXTRA_CONSTRAINT (op, 'T'))
|
||||
return 1;
|
||||
break;
|
||||
case 'U':
|
||||
if (EXTRA_CONSTRAINT (op, 'U'))
|
||||
return 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'r':
|
||||
default:
|
||||
if (GET_MODE (op) == BLKmode)
|
||||
break;
|
||||
if (register_operand (op, VOIDmode))
|
||||
/* For all other letters, we first check for a register class,
|
||||
otherwise it is an EXTRA_CONSTRAINT. */
|
||||
if (REG_CLASS_FROM_LETTER (c) != NO_REGS)
|
||||
{
|
||||
case 'r':
|
||||
if (GET_MODE (op) == BLKmode)
|
||||
break;
|
||||
if (register_operand (op, VOIDmode))
|
||||
return 1;
|
||||
}
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
if (EXTRA_CONSTRAINT (op, c))
|
||||
return 1;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2138,9 +2125,6 @@ preprocess_constraints ()
|
|||
case 's': case 'i': case 'n':
|
||||
case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P':
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
case 'Q': case 'R': case 'S': case 'T': case 'U':
|
||||
#endif
|
||||
/* These don't say anything we care about. */
|
||||
break;
|
||||
|
||||
|
@ -2372,20 +2356,6 @@ constrain_operands (strict)
|
|||
win = 1;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (strict < 0
|
||||
|| (strict == 0
|
||||
&& GET_CODE (op) == REG
|
||||
&& REGNO (op) >= FIRST_PSEUDO_REGISTER)
|
||||
|| (strict == 0 && GET_CODE (op) == SCRATCH)
|
||||
|| (GET_CODE (op) == REG
|
||||
&& ((GENERAL_REGS == ALL_REGS
|
||||
&& REGNO (op) < FIRST_PSEUDO_REGISTER)
|
||||
|| reg_fits_class_p (op, GENERAL_REGS,
|
||||
offset, mode))))
|
||||
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
|
||||
|
@ -2472,17 +2442,6 @@ constrain_operands (strict)
|
|||
win = 1;
|
||||
break;
|
||||
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
case 'Q':
|
||||
case 'R':
|
||||
case 'S':
|
||||
case 'T':
|
||||
case 'U':
|
||||
if (EXTRA_CONSTRAINT (op, c))
|
||||
win = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'V':
|
||||
if (GET_CODE (op) == MEM
|
||||
&& ((strict > 0 && ! offsettable_memref_p (op))
|
||||
|
@ -2507,15 +2466,27 @@ constrain_operands (strict)
|
|||
break;
|
||||
|
||||
default:
|
||||
if (strict < 0
|
||||
|| (strict == 0
|
||||
&& GET_CODE (op) == REG
|
||||
&& REGNO (op) >= FIRST_PSEUDO_REGISTER)
|
||||
|| (strict == 0 && GET_CODE (op) == SCRATCH)
|
||||
|| (GET_CODE (op) == REG
|
||||
&& reg_fits_class_p (op, REG_CLASS_FROM_LETTER (c),
|
||||
offset, mode)))
|
||||
win = 1;
|
||||
{
|
||||
enum reg_class class;
|
||||
|
||||
class = (c == 'r' ? GENERAL_REGS : REG_CLASS_FROM_LETTER (c));
|
||||
if (class != NO_REGS)
|
||||
{
|
||||
if (strict < 0
|
||||
|| (strict == 0
|
||||
&& GET_CODE (op) == REG
|
||||
&& REGNO (op) >= FIRST_PSEUDO_REGISTER)
|
||||
|| (strict == 0 && GET_CODE (op) == SCRATCH)
|
||||
|| (GET_CODE (op) == REG
|
||||
&& reg_fits_class_p (op, class, offset, mode)))
|
||||
win = 1;
|
||||
}
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
else if (EXTRA_CONSTRAINT (op, c))
|
||||
win = 1;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
constraints[opno] = p;
|
||||
|
|
|
@ -1561,17 +1561,6 @@ record_reg_classes (n_alts, n_ops, ops, modes,
|
|||
win = 1;
|
||||
break;
|
||||
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
case 'Q':
|
||||
case 'R':
|
||||
case 'S':
|
||||
case 'T':
|
||||
case 'U':
|
||||
if (EXTRA_CONSTRAINT (op, c))
|
||||
win = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'g':
|
||||
if (GET_CODE (op) == MEM
|
||||
|| (CONSTANT_P (op)
|
||||
|
@ -1587,9 +1576,15 @@ record_reg_classes (n_alts, n_ops, ops, modes,
|
|||
break;
|
||||
|
||||
default:
|
||||
classes[i]
|
||||
= reg_class_subunion[(int) classes[i]]
|
||||
[(int) REG_CLASS_FROM_LETTER (c)];
|
||||
if (REG_CLASS_FROM_LETTER (c) != NO_REGS)
|
||||
classes[i]
|
||||
= reg_class_subunion[(int) classes[i]]
|
||||
[(int) REG_CLASS_FROM_LETTER (c)];
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
else if (EXTRA_CONSTRAINT (op, c))
|
||||
win = 1;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
constraints[i] = p;
|
||||
|
|
21
gcc/reload.c
21
gcc/reload.c
|
@ -3142,21 +3142,18 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|
|||
= (int) reg_class_subunion[this_alternative[i]][(int) GENERAL_REGS];
|
||||
goto reg;
|
||||
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
case 'Q':
|
||||
case 'R':
|
||||
case 'S':
|
||||
case 'T':
|
||||
case 'U':
|
||||
if (EXTRA_CONSTRAINT (operand, c))
|
||||
win = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
|
||||
{
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
if (EXTRA_CONSTRAINT (operand, c))
|
||||
win = 1;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
this_alternative[i]
|
||||
= (int) reg_class_subunion[this_alternative[i]][(int) REG_CLASS_FROM_LETTER (c)];
|
||||
|
||||
reg:
|
||||
if (GET_MODE (operand) == BLKmode)
|
||||
break;
|
||||
|
|
|
@ -1276,9 +1276,6 @@ maybe_fix_stack_asms ()
|
|||
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':
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
case 'Q': case 'R': case 'S': case 'T': case 'U':
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
|
@ -8189,9 +8186,6 @@ reload_cse_simplify_operands (insn)
|
|||
case 's': case 'i': case 'n':
|
||||
case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P':
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
case 'Q': case 'R': case 'S': case 'T': case 'U':
|
||||
#endif
|
||||
case 'p': case 'X':
|
||||
/* These don't say anything we care about. */
|
||||
break;
|
||||
|
|
51
gcc/stmt.c
51
gcc/stmt.c
|
@ -1508,17 +1508,34 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
|||
break;
|
||||
|
||||
case 'g': case 'X':
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
case 'Q': case 'R': case 'S': case 'T': case 'U':
|
||||
#endif
|
||||
allows_reg = 1;
|
||||
allows_mem = 1;
|
||||
break;
|
||||
|
||||
case 'p': case 'r':
|
||||
default:
|
||||
allows_reg = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (! ISALPHA (constraint[j]))
|
||||
{
|
||||
error ("invalid punctuation `%c' in constraint",
|
||||
constraint[j]);
|
||||
return;
|
||||
}
|
||||
if (REG_CLASS_FROM_LETTER (constraint[j]) != NO_REGS)
|
||||
allows_reg = 1;
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
else
|
||||
{
|
||||
/* Otherwise we can't assume anything about the nature of
|
||||
the constraint except that it isn't purely registers.
|
||||
Treat it like "g" and hope for the best. */
|
||||
allows_reg = 1;
|
||||
allows_mem = 1;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
/* If an output operand is not a decl or indirect ref and our constraint
|
||||
|
@ -1681,18 +1698,34 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
|||
/* ... fall through ... */
|
||||
|
||||
case 'p': case 'r':
|
||||
default:
|
||||
allows_reg = 1;
|
||||
break;
|
||||
|
||||
case 'g': case 'X':
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
case 'Q': case 'R': case 'S': case 'T': case 'U':
|
||||
#endif
|
||||
|
||||
allows_reg = 1;
|
||||
allows_mem = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (! ISALPHA (constraint[j]))
|
||||
{
|
||||
error ("invalid punctuation `%c' in constraint",
|
||||
constraint[j]);
|
||||
return;
|
||||
}
|
||||
if (REG_CLASS_FROM_LETTER (constraint[j]) != NO_REGS)
|
||||
allows_reg = 1;
|
||||
#ifdef EXTRA_CONSTRAINT
|
||||
else
|
||||
{
|
||||
/* Otherwise we can't assume anything about the nature of
|
||||
the constraint except that it isn't purely registers.
|
||||
Treat it like "g" and hope for the best. */
|
||||
allows_reg = 1;
|
||||
allows_mem = 1;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if (! allows_reg && allows_mem)
|
||||
|
|
20
gcc/tm.texi
20
gcc/tm.texi
|
@ -2180,17 +2180,19 @@ between these kinds.
|
|||
@findex EXTRA_CONSTRAINT
|
||||
@item EXTRA_CONSTRAINT (@var{value}, @var{c})
|
||||
A C expression that defines the optional machine-dependent constraint
|
||||
letters (@samp{Q}, @samp{R}, @samp{S}, @samp{T}, @samp{U}) that can
|
||||
be used to segregate specific types of operands, usually memory
|
||||
references, for the target machine. Normally this macro will not be
|
||||
defined. If it is required for a particular target machine, it should
|
||||
return 1 if @var{value} corresponds to the operand type represented by
|
||||
the constraint letter @var{c}. If @var{c} is not defined as an extra
|
||||
letters that can be used to segregate specific types of operands, usually
|
||||
memory references, for the target machine. Any letter that is not
|
||||
elsewhere defined and not matched by @code{REG_CLASS_FROM_LETTER}
|
||||
may be used. Normally this macro will not be defined.
|
||||
|
||||
If it is required for a particular target machine, it should return 1
|
||||
if @var{value} corresponds to the operand type represented by the
|
||||
constraint letter @var{c}. If @var{c} is not defined as an extra
|
||||
constraint, the value returned should be 0 regardless of @var{value}.
|
||||
|
||||
For example, on the ROMP, load instructions cannot have their output in r0 if
|
||||
the memory reference contains a symbolic address. Constraint letter
|
||||
@samp{Q} is defined as representing a memory address that does
|
||||
For example, on the ROMP, load instructions cannot have their output
|
||||
in r0 if the memory reference contains a symbolic address. Constraint
|
||||
letter @samp{Q} is defined as representing a memory address that does
|
||||
@emph{not} contain a symbolic address. An alternative is specified with
|
||||
a @samp{Q} constraint on the input and @samp{r} on the output. The next
|
||||
alternative specifies @samp{m} on the input and a register class that
|
||||
|
|
Loading…
Reference in New Issue