else if (new->number != number || new->type != type)
as_warn (_("ignoring redefinition of register alias '%s'"), str);
- return 0;
+ return NULL;
}
name = xstrdup (str);
new_register_name .req existing_register_name
If we find one, or if it looks sufficiently like one that we want to
- handle any error here, return non-zero. Otherwise return zero. */
+ handle any error here, return TRUE. Otherwise return FALSE. */
-static int
+static bfd_boolean
create_register_alias (char * newname, char *p)
{
struct reg_entry *old;
collapsed to single spaces. */
oldname = p;
if (strncmp (oldname, " .req ", 6) != 0)
- return 0;
+ return FALSE;
oldname += 6;
if (*oldname == '\0')
- return 0;
+ return FALSE;
old = hash_find (arm_reg_hsh, oldname);
if (!old)
{
as_warn (_("unknown register '%s' -- .req ignored"), oldname);
- return 1;
+ return TRUE;
}
/* If TC_CASE_SENSITIVE is defined, then newname already points to
/* Create aliases under the new name as stated; an all-lowercase
version of the new name; and an all-uppercase version of the new
name. */
- insert_reg_alias (nbuf, old->number, old->type);
-
- for (p = nbuf; *p; p++)
- *p = TOUPPER (*p);
+ if (insert_reg_alias (nbuf, old->number, old->type) != NULL)
+ {
+ for (p = nbuf; *p; p++)
+ *p = TOUPPER (*p);
- if (strncmp (nbuf, newname, nlen))
- insert_reg_alias (nbuf, old->number, old->type);
+ if (strncmp (nbuf, newname, nlen))
+ {
+ /* If this attempt to create an additional alias fails, do not bother
+ trying to create the all-lower case alias. We will fail and issue
+ a second, duplicate error message. This situation arises when the
+ programmer does something like:
+ foo .req r0
+ Foo .req r1
+ The second .req creates the "Foo" alias but then fails to create
+ the artifical FOO alias because it has already been created by the
+ first .req. */
+ if (insert_reg_alias (nbuf, old->number, old->type) == NULL)
+ return TRUE;
+ }
- for (p = nbuf; *p; p++)
- *p = TOLOWER (*p);
+ for (p = nbuf; *p; p++)
+ *p = TOLOWER (*p);
- if (strncmp (nbuf, newname, nlen))
- insert_reg_alias (nbuf, old->number, old->type);
+ if (strncmp (nbuf, newname, nlen))
+ insert_reg_alias (nbuf, old->number, old->type);
+ }
- return 1;
+ return TRUE;
}
/* Create a Neon typed/indexed register alias using directives, e.g.:
name);
else
{
+ char * p;
+ char * nbuf;
+
hash_delete (arm_reg_hsh, name);
free ((char *) reg->name);
if (reg->neon)
free (reg->neon);
free (reg);
+
+ /* Also locate the all upper case and all lower case versions.
+ Do not complain if we cannot find one or the other as it
+ was probably deleted above. */
+
+ nbuf = strdup (name);
+ for (p = nbuf; *p; p++)
+ *p = TOUPPER (*p);
+ reg = hash_find (arm_reg_hsh, nbuf);
+ if (reg)
+ {
+ hash_delete (arm_reg_hsh, nbuf);
+ free ((char *) reg->name);
+ if (reg->neon)
+ free (reg->neon);
+ free (reg);
+ }
+
+ for (p = nbuf; *p; p++)
+ *p = TOLOWER (*p);
+ reg = hash_find (arm_reg_hsh, nbuf);
+ if (reg)
+ {
+ hash_delete (arm_reg_hsh, nbuf);
+ free ((char *) reg->name);
+ if (reg->neon)
+ free (reg->neon);
+ free (reg);
+ }
+
+ free (nbuf);
}
}
# Attempt to remove the builtin alias for r0.
.unreq r0
-
+
# That is ignored, so this should still work.
add r0, r0, r0
-
+
+ # Now attempt to re-alias foo. There used to be a bug whereby the
+ # first creation of an alias called foo would also create an alias
+ # called FOO, but the .unreq of foo would not delete FOO. Thus a
+ # second attempt at aliasing foo (to something different than
+ # before) would fail because the assembler would complain that FOO
+ # already existed.
+ foo .req r1
+
+ add foo, foo, foo
+
+ # Check that the upper case alias was also recreated.
+ add FOO, FOO, FOO
+
+ # Check that a second attempt to alias foo, using a mixed case
+ # verison of the name, will fail.
+ Foo .req r2