unsigned int hashcode;
struct attr_hash *h;
struct obstack *old_obstack = rtl_obstack;
+ int permanent_p = 1;
/* For each of several cases, search the hash table for an existing entry.
Use that entry if one is found; otherwise create a new RTL and add it
{
rtx arg0 = va_arg (p, rtx);
- /* A permanent object cannot point to impermanent ones. */
if (! ATTR_PERMANENT_P (arg0))
- {
- rt_val = rtx_alloc (code);
- XEXP (rt_val, 0) = arg0;
- return rt_val;
- }
+ permanent_p = 0;
hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
rtx arg0 = va_arg (p, rtx);
rtx arg1 = va_arg (p, rtx);
- /* A permanent object cannot point to impermanent ones. */
if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
- {
- rt_val = rtx_alloc (code);
- XEXP (rt_val, 0) = arg0;
- XEXP (rt_val, 1) = arg1;
- return rt_val;
- }
+ permanent_p = 0;
hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
&& GET_CODE (h->u.rtl) == code
&& XEXP (h->u.rtl, 0) == arg0
&& XEXP (h->u.rtl, 1) == arg1)
- return h->u.rtl;
+ {
+ ATTR_CURR_SIMPLIFIED_P (h->u.rtl) = 0;
+ return h->u.rtl;
+ }
if (h == 0)
{
char *arg0 = va_arg (p, char *);
char *arg1 = va_arg (p, char *);
+ arg0 = DEF_ATTR_STRING (arg0);
+ arg1 = DEF_ATTR_STRING (arg1);
+
hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
if (h->hashcode == hashcode
XSTR (rt_val, 1) = arg1;
}
}
+ else if (GET_RTX_LENGTH (code) == 2
+ && GET_RTX_FORMAT (code)[0] == 'i'
+ && GET_RTX_FORMAT (code)[1] == 'i')
+ {
+ int arg0 = va_arg (p, int);
+ int arg1 = va_arg (p, int);
+
+ hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
+ for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
+ if (h->hashcode == hashcode
+ && GET_CODE (h->u.rtl) == code
+ && XINT (h->u.rtl, 0) == arg0
+ && XINT (h->u.rtl, 1) == arg1)
+ return h->u.rtl;
+
+ if (h == 0)
+ {
+ rtl_obstack = hash_obstack;
+ rt_val = rtx_alloc (code);
+ XINT (rt_val, 0) = arg0;
+ XINT (rt_val, 1) = arg1;
+ }
+ }
else if (code == CONST_INT)
{
HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
rtl_obstack = old_obstack;
attr_hash_add_rtx (hashcode, rt_val);
- ATTR_PERMANENT_P (rt_val) = 1;
+ ATTR_PERMANENT_P (rt_val) = permanent_p;
return rt_val;
}
static rtx
attr_eq (const char *name, const char *value)
{
- return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
+ return attr_rtx (EQ_ATTR, name, value);
}
static const char *
&& rtx_equal_p (x, y)));
}
-/* Copy an attribute value expression,
- descending to all depths, but not copying any
- permanent hashed subexpressions. */
-
-static rtx
-attr_copy_rtx (rtx orig)
-{
- rtx copy;
- int i, j;
- RTX_CODE code;
- const char *format_ptr;
-
- /* No need to copy a permanent object. */
- if (ATTR_PERMANENT_P (orig))
- return orig;
-
- code = GET_CODE (orig);
-
- switch (code)
- {
- case REG:
- CASE_CONST_ANY:
- case SYMBOL_REF:
- case MATCH_TEST:
- case CODE_LABEL:
- case PC:
- case CC0:
- return orig;
-
- default:
- break;
- }
-
- copy = rtx_alloc (code);
- PUT_MODE (copy, GET_MODE (orig));
- ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
- ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
- ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
-
- format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
-
- for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
- {
- switch (*format_ptr++)
- {
- case 'e':
- XEXP (copy, i) = XEXP (orig, i);
- if (XEXP (orig, i) != NULL)
- XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
- break;
-
- case 'E':
- case 'V':
- XVEC (copy, i) = XVEC (orig, i);
- if (XVEC (orig, i) != NULL)
- {
- XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
- for (j = 0; j < XVECLEN (copy, i); j++)
- XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
- }
- break;
-
- case 'n':
- case 'i':
- XINT (copy, i) = XINT (orig, i);
- break;
-
- case 'w':
- XWINT (copy, i) = XWINT (orig, i);
- break;
-
- case 's':
- case 'S':
- XSTR (copy, i) = XSTR (orig, i);
- break;
-
- default:
- gcc_unreachable ();
- }
- }
- return copy;
-}
-
/* Given a test expression EXP for attribute ATTR, ensure it is validly
formed. LOC is the location of the .md construct that contains EXP.
XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
XVECEXP (exp, 0, i + 1)
= make_canonical (loc, attr, XVECEXP (exp, 0, i + 1));
- if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
+ if (! attr_equal_p (XVECEXP (exp, 0, i + 1), defval))
allsame = 0;
}
if (allsame)
if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
copy_boolean (XEXP (exp, 1)));
+ else if (GET_CODE (exp) == NOT)
+ return attr_rtx (NOT, copy_boolean (XEXP (exp, 0)));
if (GET_CODE (exp) == MATCH_OPERAND)
{
XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
}
for (av = attr->first_value; av; av = av->next)
- if (rtx_equal_p (value, av->value)
+ if (attr_equal_p (value, av->value)
&& (num_alt == 0 || av->first_insn == NULL
|| insn_alternatives[av->first_insn->def->insn_code]))
return av;
rtl_obstack = temp_obstack;
x = simplify_test_exp (exp, insn_code, insn_index);
rtl_obstack = old;
- if (x == exp || rtl_obstack == temp_obstack)
- return x;
- return attr_copy_rtx (x);
+ return x;
}
/* Returns true if S1 is a subset of S2. */
static rtx
attr_alt_intersection (rtx s1, rtx s2)
{
- rtx result = rtx_alloc (EQ_ATTR_ALT);
+ int result;
switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
{
case (0 << 1) | 0:
- XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
+ result = XINT (s1, 0) & XINT (s2, 0);
break;
case (0 << 1) | 1:
- XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
+ result = XINT (s1, 0) & ~XINT (s2, 0);
break;
case (1 << 1) | 0:
- XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
+ result = XINT (s2, 0) & ~XINT (s1, 0);
break;
case (1 << 1) | 1:
- XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
+ result = XINT (s1, 0) | XINT (s2, 0);
break;
default:
gcc_unreachable ();
}
- XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
- return result;
+ return attr_rtx (EQ_ATTR_ALT, result, XINT (s1, 1) & XINT (s2, 1));
}
/* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
static rtx
attr_alt_union (rtx s1, rtx s2)
{
- rtx result = rtx_alloc (EQ_ATTR_ALT);
+ int result;
switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
{
case (0 << 1) | 0:
- XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
+ result = XINT (s1, 0) | XINT (s2, 0);
break;
case (0 << 1) | 1:
- XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
+ result = XINT (s2, 0) & ~XINT (s1, 0);
break;
case (1 << 1) | 0:
- XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
+ result = XINT (s1, 0) & ~XINT (s2, 0);
break;
case (1 << 1) | 1:
- XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
+ result = XINT (s1, 0) & XINT (s2, 0);
break;
default:
gcc_unreachable ();
}
- XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
- return result;
+ return attr_rtx (EQ_ATTR_ALT, result, XINT (s1, 1) | XINT (s2, 1));
}
/* Return EQ_ATTR_ALT expression representing complement of S. */
static rtx
attr_alt_complement (rtx s)
{
- rtx result = rtx_alloc (EQ_ATTR_ALT);
-
- XINT (result, 0) = XINT (s, 0);
- XINT (result, 1) = 1 - XINT (s, 1);
-
- return result;
+ return attr_rtx (EQ_ATTR_ALT, XINT (s, 0), 1 - XINT (s, 1));
}
/* Return EQ_ATTR_ALT expression representing set containing elements set
static rtx
mk_attr_alt (uint64_t e)
{
- rtx result = rtx_alloc (EQ_ATTR_ALT);
-
- XINT (result, 0) = e;
- XINT (result, 1) = 0;
-
- return result;
+ return attr_rtx (EQ_ATTR_ALT, (int)e, 0);
}
/* Given an expression, see if it can be simplified for a particular insn
&& attr_rtx_cost (newexp) < 26
)
{
- newexp = attr_copy_rtx (newexp);
remove_insn_ent (av, ie);
av = get_attr_value (ie->def->loc, newexp, attr,
ie->def->insn_code);
{
int j;
char *name;
- rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0));
+ rtx test = attr_eq (tune_attr->name, XSTR (val->value, 0));
if (val == tune_attr->default_val)
continue;