mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-25 10:40:56 +08:00
rtl.h (ASM_OPERANDS_INPUT_CONSTRAINT_EXP): New macro.
* rtl.h (ASM_OPERANDS_INPUT_CONSTRAINT_EXP): New macro. * gcse.c (hash_string_1): New function. (hash_expr_1) <ASM_OPERANDS>: Disregard filename and line number. (expr_equiv_p) <ASM_OPERANDS>: Likewise. * cse.c (rtx_cost): Don't increase the cost of ASM_OPERANDS. (canon_hash_string): New function. (canon_hash) <ASM_OPERANDS>: Disregard filename and line number. (exp_equiv_p) <ASM_OPERANDS>: Likewise. (fold_rtx): Use ASM_OPERANDS accessor macros. * emit-rtl.c (copy_insn_1): Likewise. * integrate.c (copy_rtx_and_substitute): Likewise. * stmt.c (expand_asm_operands): Likewise. Give an ASM_OPERANDS rtx the mode of the output reg being set from it. From-SVN: r36110
This commit is contained in:
parent
298ec8f42f
commit
6462bb432f
@ -1,3 +1,19 @@
|
||||
2000-09-01 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* rtl.h (ASM_OPERANDS_INPUT_CONSTRAINT_EXP): New macro.
|
||||
* gcse.c (hash_string_1): New function.
|
||||
(hash_expr_1) <ASM_OPERANDS>: Disregard filename and line number.
|
||||
(expr_equiv_p) <ASM_OPERANDS>: Likewise.
|
||||
* cse.c (rtx_cost): Don't increase the cost of ASM_OPERANDS.
|
||||
(canon_hash_string): New function.
|
||||
(canon_hash) <ASM_OPERANDS>: Disregard filename and line number.
|
||||
(exp_equiv_p) <ASM_OPERANDS>: Likewise.
|
||||
(fold_rtx): Use ASM_OPERANDS accessor macros.
|
||||
* emit-rtl.c (copy_insn_1): Likewise.
|
||||
* integrate.c (copy_rtx_and_substitute): Likewise.
|
||||
* stmt.c (expand_asm_operands): Likewise. Give an
|
||||
ASM_OPERANDS rtx the mode of the output reg being set from it.
|
||||
|
||||
2000-09-01 Fred Fish <fnf@be.com>
|
||||
|
||||
* fix-header.c (write_rbrac): Add putc and getc to list of
|
||||
|
91
gcc/cse.c
91
gcc/cse.c
@ -787,12 +787,6 @@ rtx_cost (x, outer_code)
|
||||
/* Used in loop.c and combine.c as a marker. */
|
||||
total = 0;
|
||||
break;
|
||||
case ASM_OPERANDS:
|
||||
/* We don't want these to be used in substitutions because
|
||||
we have no way of validating the resulting insn. So assign
|
||||
anything containing an ASM_OPERANDS a very high cost. */
|
||||
total = 1000;
|
||||
break;
|
||||
default:
|
||||
total = 2;
|
||||
}
|
||||
@ -2141,6 +2135,21 @@ use_related_value (x, elt)
|
||||
return plus_constant (q->exp, offset);
|
||||
}
|
||||
|
||||
/* Hash a string. Just add its bytes up. */
|
||||
static inline unsigned
|
||||
canon_hash_string (ps)
|
||||
const char *ps;
|
||||
{
|
||||
unsigned hash = 0;
|
||||
const unsigned char *p = (const unsigned char *)ps;
|
||||
|
||||
if (p)
|
||||
while (*p)
|
||||
hash += *p++;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* Hash an rtx. We are careful to make sure the value is never negative.
|
||||
Equivalent registers hash identically.
|
||||
MODE is used in hashing for CONST_INTs only;
|
||||
@ -2286,6 +2295,32 @@ canon_hash (x, mode)
|
||||
do_not_record = 1;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't want to take the filename and line into account. */
|
||||
hash += (unsigned) code + (unsigned) GET_MODE (x)
|
||||
+ canon_hash_string (ASM_OPERANDS_TEMPLATE (x))
|
||||
+ canon_hash_string (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
|
||||
+ (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);
|
||||
|
||||
if (ASM_OPERANDS_INPUT_LENGTH (x))
|
||||
{
|
||||
for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
|
||||
{
|
||||
hash += (canon_hash (ASM_OPERANDS_INPUT (x, i),
|
||||
GET_MODE (ASM_OPERANDS_INPUT (x, i)))
|
||||
+ canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT
|
||||
(x, i)));
|
||||
}
|
||||
|
||||
hash += canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
|
||||
x = ASM_OPERANDS_INPUT (x, 0);
|
||||
mode = GET_MODE (x);
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2315,14 +2350,7 @@ canon_hash (x, mode)
|
||||
for (j = 0; j < XVECLEN (x, i); j++)
|
||||
hash += canon_hash (XVECEXP (x, i, j), 0);
|
||||
else if (fmt[i] == 's')
|
||||
{
|
||||
register const unsigned char *p =
|
||||
(const unsigned char *) XSTR (x, i);
|
||||
|
||||
if (p)
|
||||
while (*p)
|
||||
hash += *p++;
|
||||
}
|
||||
hash += canon_hash_string (XSTR (x, i));
|
||||
else if (fmt[i] == 'i')
|
||||
{
|
||||
register unsigned tem = XINT (x, i);
|
||||
@ -2476,6 +2504,35 @@ exp_equiv_p (x, y, validate, equal_values)
|
||||
&& exp_equiv_p (XEXP (x, 1), XEXP (y, 0),
|
||||
validate, equal_values)));
|
||||
|
||||
case ASM_OPERANDS:
|
||||
/* We don't use the generic code below because we want to
|
||||
disregard filename and line numbers. */
|
||||
|
||||
/* A volatile asm isn't equivalent to any other. */
|
||||
if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
|
||||
return 0;
|
||||
|
||||
if (GET_MODE (x) != GET_MODE (y)
|
||||
|| strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y))
|
||||
|| strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x),
|
||||
ASM_OPERANDS_OUTPUT_CONSTRAINT (y))
|
||||
|| ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y)
|
||||
|| ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y))
|
||||
return 0;
|
||||
|
||||
if (ASM_OPERANDS_INPUT_LENGTH (x))
|
||||
{
|
||||
for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
|
||||
if (! exp_equiv_p (ASM_OPERANDS_INPUT (x, i),
|
||||
ASM_OPERANDS_INPUT (y, i),
|
||||
validate, equal_values)
|
||||
|| strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
|
||||
ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -3500,9 +3557,9 @@ fold_rtx (x, insn)
|
||||
}
|
||||
|
||||
case ASM_OPERANDS:
|
||||
for (i = XVECLEN (x, 3) - 1; i >= 0; i--)
|
||||
validate_change (insn, &XVECEXP (x, 3, i),
|
||||
fold_rtx (XVECEXP (x, 3, i), insn), 0);
|
||||
for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
|
||||
validate_change (insn, &ASM_OPERANDS_INPUT (x, i),
|
||||
fold_rtx (ASM_OPERANDS_INPUT (x, i), insn), 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -3913,10 +3913,10 @@ copy_insn_1 (orig)
|
||||
}
|
||||
else if (code == ASM_OPERANDS)
|
||||
{
|
||||
orig_asm_operands_vector = XVEC (orig, 3);
|
||||
copy_asm_operands_vector = XVEC (copy, 3);
|
||||
orig_asm_constraints_vector = XVEC (orig, 4);
|
||||
copy_asm_constraints_vector = XVEC (copy, 4);
|
||||
orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig);
|
||||
copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy);
|
||||
orig_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (orig);
|
||||
copy_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);
|
||||
}
|
||||
|
||||
return copy;
|
||||
|
77
gcc/gcse.c
77
gcc/gcse.c
@ -1333,6 +1333,20 @@ hash_expr (x, mode, do_not_record_p, hash_table_size)
|
||||
hash = hash_expr_1 (x, mode, do_not_record_p);
|
||||
return hash % hash_table_size;
|
||||
}
|
||||
/* Hash a string. Just add its bytes up. */
|
||||
static inline unsigned
|
||||
hash_string_1 (ps)
|
||||
const char *ps;
|
||||
{
|
||||
unsigned hash = 0;
|
||||
const unsigned char *p = (const unsigned char *)ps;
|
||||
|
||||
if (p)
|
||||
while (*p)
|
||||
hash += *p++;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* Subroutine of hash_expr to do the actual work. */
|
||||
|
||||
@ -1433,6 +1447,32 @@ hash_expr_1 (x, mode, do_not_record_p)
|
||||
*do_not_record_p = 1;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't want to take the filename and line into account. */
|
||||
hash += (unsigned) code + (unsigned) GET_MODE (x)
|
||||
+ hash_string_1 (ASM_OPERANDS_TEMPLATE (x))
|
||||
+ hash_string_1 (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
|
||||
+ (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);
|
||||
|
||||
if (ASM_OPERANDS_INPUT_LENGTH (x))
|
||||
{
|
||||
for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
|
||||
{
|
||||
hash += (hash_expr_1 (ASM_OPERANDS_INPUT (x, i),
|
||||
GET_MODE (ASM_OPERANDS_INPUT (x, i)),
|
||||
do_not_record_p)
|
||||
+ hash_string_1 (ASM_OPERANDS_INPUT_CONSTRAINT
|
||||
(x, i)));
|
||||
}
|
||||
|
||||
hash += hash_string_1 (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
|
||||
x = ASM_OPERANDS_INPUT (x, 0);
|
||||
mode = GET_MODE (x);
|
||||
goto repeat;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -1466,14 +1506,7 @@ hash_expr_1 (x, mode, do_not_record_p)
|
||||
}
|
||||
|
||||
else if (fmt[i] == 's')
|
||||
{
|
||||
register const unsigned char *p =
|
||||
(const unsigned char *) XSTR (x, i);
|
||||
|
||||
if (p)
|
||||
while (*p)
|
||||
hash += *p++;
|
||||
}
|
||||
hash += hash_string_1 (XSTR (x, i));
|
||||
else if (fmt[i] == 'i')
|
||||
hash += (unsigned int) XINT (x, i);
|
||||
else
|
||||
@ -1565,6 +1598,34 @@ expr_equiv_p (x, y)
|
||||
|| (expr_equiv_p (XEXP (x, 0), XEXP (y, 1))
|
||||
&& expr_equiv_p (XEXP (x, 1), XEXP (y, 0))));
|
||||
|
||||
case ASM_OPERANDS:
|
||||
/* We don't use the generic code below because we want to
|
||||
disregard filename and line numbers. */
|
||||
|
||||
/* A volatile asm isn't equivalent to any other. */
|
||||
if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
|
||||
return 0;
|
||||
|
||||
if (GET_MODE (x) != GET_MODE (y)
|
||||
|| strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y))
|
||||
|| strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x),
|
||||
ASM_OPERANDS_OUTPUT_CONSTRAINT (y))
|
||||
|| ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y)
|
||||
|| ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y))
|
||||
return 0;
|
||||
|
||||
if (ASM_OPERANDS_INPUT_LENGTH (x))
|
||||
{
|
||||
for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
|
||||
if (! expr_equiv_p (ASM_OPERANDS_INPUT (x, i),
|
||||
ASM_OPERANDS_INPUT (y, i))
|
||||
|| strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
|
||||
ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2040,20 +2040,23 @@ copy_rtx_and_substitute (orig, map, for_lhs)
|
||||
break;
|
||||
|
||||
case ASM_OPERANDS:
|
||||
/* If a single asm insn contains multiple output operands
|
||||
then it contains multiple ASM_OPERANDS rtx's that share operand 3.
|
||||
We must make sure that the copied insn continues to share it. */
|
||||
if (map->orig_asm_operands_vector == XVEC (orig, 3))
|
||||
/* If a single asm insn contains multiple output operands then
|
||||
it contains multiple ASM_OPERANDS rtx's that share the input
|
||||
and constraint vecs. We must make sure that the copied insn
|
||||
continues to share it. */
|
||||
if (map->orig_asm_operands_vector == ASM_OPERANDS_INPUT_VEC (orig))
|
||||
{
|
||||
copy = rtx_alloc (ASM_OPERANDS);
|
||||
copy->volatil = orig->volatil;
|
||||
XSTR (copy, 0) = XSTR (orig, 0);
|
||||
XSTR (copy, 1) = XSTR (orig, 1);
|
||||
XINT (copy, 2) = XINT (orig, 2);
|
||||
XVEC (copy, 3) = map->copy_asm_operands_vector;
|
||||
XVEC (copy, 4) = map->copy_asm_constraints_vector;
|
||||
XSTR (copy, 5) = XSTR (orig, 5);
|
||||
XINT (copy, 6) = XINT (orig, 6);
|
||||
ASM_OPERANDS_TEMPLATE (copy) = ASM_OPERANDS_TEMPLATE (orig);
|
||||
ASM_OPERANDS_OUTPUT_CONSTRAINT (copy)
|
||||
= ASM_OPERANDS_OUTPUT_CONSTRAINT (orig);
|
||||
ASM_OPERANDS_OUTPUT_IDX (copy) = ASM_OPERANDS_OUTPUT_IDX (orig);
|
||||
ASM_OPERANDS_INPUT_VEC (copy) = map->copy_asm_operands_vector;
|
||||
ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy)
|
||||
= map->copy_asm_constraints_vector;
|
||||
ASM_OPERANDS_SOURCE_FILE (copy) = ASM_OPERANDS_SOURCE_FILE (orig);
|
||||
ASM_OPERANDS_SOURCE_LINE (copy) = ASM_OPERANDS_SOURCE_LINE (orig);
|
||||
return copy;
|
||||
}
|
||||
break;
|
||||
@ -2212,9 +2215,10 @@ copy_rtx_and_substitute (orig, map, for_lhs)
|
||||
|
||||
if (code == ASM_OPERANDS && map->orig_asm_operands_vector == 0)
|
||||
{
|
||||
map->orig_asm_operands_vector = XVEC (orig, 3);
|
||||
map->copy_asm_operands_vector = XVEC (copy, 3);
|
||||
map->copy_asm_constraints_vector = XVEC (copy, 4);
|
||||
map->orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig);
|
||||
map->copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy);
|
||||
map->copy_asm_constraints_vector
|
||||
= ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);
|
||||
}
|
||||
|
||||
return copy;
|
||||
|
@ -800,6 +800,8 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
|
||||
#define ASM_OPERANDS_INPUT_CONSTRAINT_VEC(RTX) XCVEC ((RTX), 4, ASM_OPERANDS)
|
||||
#define ASM_OPERANDS_INPUT(RTX, N) XCVECEXP ((RTX), 3, (N), ASM_OPERANDS)
|
||||
#define ASM_OPERANDS_INPUT_LENGTH(RTX) XCVECLEN ((RTX), 3, ASM_OPERANDS)
|
||||
#define ASM_OPERANDS_INPUT_CONSTRAINT_EXP(RTX, N) \
|
||||
XCVECEXP ((RTX), 4, (N), ASM_OPERANDS)
|
||||
#define ASM_OPERANDS_INPUT_CONSTRAINT(RTX, N) \
|
||||
XSTR (XCVECEXP ((RTX), 4, (N), ASM_OPERANDS), 0)
|
||||
#define ASM_OPERANDS_INPUT_MODE(RTX, N) \
|
||||
|
20
gcc/stmt.c
20
gcc/stmt.c
@ -1595,7 +1595,9 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
||||
argvec = rtvec_alloc (ninputs);
|
||||
constraints = rtvec_alloc (ninputs);
|
||||
|
||||
body = gen_rtx_ASM_OPERANDS (VOIDmode, TREE_STRING_POINTER (string),
|
||||
body = gen_rtx_ASM_OPERANDS ((noutputs == 0 ? VOIDmode
|
||||
: GET_MODE (output_rtx[0])),
|
||||
TREE_STRING_POINTER (string),
|
||||
empty_string, 0, argvec, constraints,
|
||||
filename, line);
|
||||
|
||||
@ -1771,9 +1773,9 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
||||
warning ("asm operand %d probably doesn't match constraints", i);
|
||||
}
|
||||
generating_concat_p = old_generating_concat_p;
|
||||
XVECEXP (body, 3, i) = op;
|
||||
ASM_OPERANDS_INPUT (body, i) = op;
|
||||
|
||||
XVECEXP (body, 4, i) /* constraints */
|
||||
ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, i)
|
||||
= gen_rtx_ASM_INPUT (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
|
||||
orig_constraint);
|
||||
i++;
|
||||
@ -1785,7 +1787,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
||||
generating_concat_p = 0;
|
||||
|
||||
for (i = 0; i < ninputs - ninout; i++)
|
||||
XVECEXP (body, 3, i) = protect_from_queue (XVECEXP (body, 3, i), 0);
|
||||
ASM_OPERANDS_INPUT (body, i)
|
||||
= protect_from_queue (ASM_OPERANDS_INPUT (body, i), 0);
|
||||
|
||||
for (i = 0; i < noutputs; i++)
|
||||
output_rtx[i] = protect_from_queue (output_rtx[i], 1);
|
||||
@ -1795,9 +1798,9 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
||||
{
|
||||
int j = inout_opnum[i];
|
||||
|
||||
XVECEXP (body, 3, ninputs - ninout + i) /* argvec */
|
||||
ASM_OPERANDS_INPUT (body, ninputs - ninout + i)
|
||||
= output_rtx[j];
|
||||
XVECEXP (body, 4, ninputs - ninout + i) /* constraints */
|
||||
ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, ninputs - ninout + i)
|
||||
= gen_rtx_ASM_INPUT (inout_mode[i], digit_strings[j]);
|
||||
}
|
||||
|
||||
@ -1810,7 +1813,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
||||
|
||||
if (noutputs == 1 && nclobbers == 0)
|
||||
{
|
||||
XSTR (body, 1) = TREE_STRING_POINTER (TREE_PURPOSE (outputs));
|
||||
ASM_OPERANDS_OUTPUT_CONSTRAINT (body)
|
||||
= TREE_STRING_POINTER (TREE_PURPOSE (outputs));
|
||||
insn = emit_insn (gen_rtx_SET (VOIDmode, output_rtx[0], body));
|
||||
}
|
||||
|
||||
@ -1837,7 +1841,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
||||
= gen_rtx_SET (VOIDmode,
|
||||
output_rtx[i],
|
||||
gen_rtx_ASM_OPERANDS
|
||||
(VOIDmode,
|
||||
(GET_MODE (output_rtx[i]),
|
||||
TREE_STRING_POINTER (string),
|
||||
TREE_STRING_POINTER (TREE_PURPOSE (tail)),
|
||||
i, argvec, constraints,
|
||||
|
Loading…
x
Reference in New Issue
Block a user