* 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
+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
/* 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;
}
return plus_constant (q->exp, offset);
}
\f
+/* 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;
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:
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);
&& 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;
}
}
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:
}
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;
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. */
*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;
}
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
|| (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;
}
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;
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;
#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) \
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);
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++;
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);
{
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]);
}
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));
}
= 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,