This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

patch: ".unreq" pseudo op for ARM


Attached is a patch to gas/config/tc-arm.c adding support for a
pseudo op ".unreq", which undoes definitions created with ".req".
I needed this for some GCC inline assembly code that needs to
be instantiated more than once.  It would probably be useful
to create similar a similar operation ".unequiv" as well.

BTW has there been any discussion about improving the gas macro
facilities?  Every time I've used ".macro" has involved ugly
hacks and contortions.  Would anyone be interested e.g. in some
modifications to replace it with a simple recursive evaluator
like M4 or Lisp?

-Pete

P.S. Please CC me on any replies, since I am not subscribed to
the binutils mailing lists.



--- tc-arm.c.orig	2003-07-23 14:30:39.000000000 -0500
+++ tc-arm.c	2003-07-29 13:28:26.000000000 -0500
@@ -591,7 +591,8 @@
 #define wc_register(reg)  ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)

-/* These are the standard names.  Users can add aliases with .req.  */
+/* These are the standard names.  */
+/* Users can add aliases with .req and delete them with .unreq.  */
 /* Integer Register Numbers.  */
 static const struct reg_entry rn_table[] =
 {
@@ -2324,6 +2325,7 @@
      Integer arg to pass to the function.  */

 static void s_req PARAMS ((int));
+static void s_unreq PARAMS ((int));
 static void s_align PARAMS ((int));
 static void s_bss PARAMS ((int));
 static void s_even PARAMS ((int));
@@ -2342,8 +2344,9 @@

 const pseudo_typeS md_pseudo_table[] =
 {
-  /* Never called becasue '.req' does not start line.  */
+  /* Never called because '.req' does not start line.  */
   { "req",         s_req,         0 },
+  { "unreq",       s_unreq,       0 },
   { "bss",         s_bss,         0 },
   { "align",       s_align,       0 },
   { "arm",         s_arm,         0 },
@@ -2647,6 +2650,56 @@
   as_bad (_("invalid syntax for .req directive"));
 }

+/* The .unreq directive deletes an alias which was previously defined
+   by .req.  For example:
+
+	my_alias .req r11
+   	.unreq my_alias
+*/
+static void
+s_unreq (a)
+     int a ATTRIBUTE_UNUSED;
+{
+  char *name;
+  char saved_char;
+
+  skip_whitespace(input_line_pointer);
+  name = input_line_pointer;
+
+  while (*input_line_pointer != 0
+    && *input_line_pointer != ' '
+    && *input_line_pointer != '\n')
+    ++input_line_pointer;
+
+  saved_char = *input_line_pointer;
+  *input_line_pointer = 0;
+
+  if (*name) {
+    enum arm_reg_type req_type = arm_reg_parse_any(name);
+
+    if (req_type != REG_TYPE_MAX)
+    {
+      char *temp_name = name;
+      int req_no = arm_reg_parse(&temp_name, all_reg_maps[req_type].htab);
+      if (req_no != FAIL)
+      {
+	struct reg_entry *req_entry;
+	req_entry = hash_delete (all_reg_maps[req_type].htab, name);
+	if (!req_entry)
+	  as_bad (_("unreq: missing hash entry for \"%s\""), name);
+	else
+	{
+	  free((PTR)req_entry->name);
+          free(req_entry);
+	}
+      } else as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
+    } else as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
+  } else as_bad (_("invalid syntax for .unreq directive"));
+
+  *input_line_pointer = saved_char;
+  demand_empty_rest_of_line ();
+}
+
 static void
 s_bss (ignore)
      int ignore ATTRIBUTE_UNUSED;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]