PATCH: support for CGEN string-macro insns

Greg McGary greg@mcgary.org
Mon Apr 2 09:37:00 GMT 2001


This is the gas side of a provisionally-accepted new feature for CGEN.
The rationale for this change should be made clear by the comment
around the call to md_assemble.

Background:
  CGEN string macro insns support unified mnemonics for a wide range of
  operand types.  Consider a hypothetical RISC ISA that handles 16-bit
  signed immediates.  We can define a single mnemonic `mov' that does
  all of the following source operand types:

    register
    16-bit immediate
    32-bit immediate

  The register and 16-bit immediate cases assemble as hard insns.
  The 32-bit immediate assembles as a string macro expansion of
  two insns to move high and low order 16-bits.

  The CGEN md_assemble chooses one of the three alternatives based on
  operand constraints.

If the change is acceptable, I can commit it myself.

Thanks.

2001-04-02  Greg McGary  <greg@mcgary.org>

	* tc.h (md_assemble): Conditionalize return-value decl.
	* read.c (read_a_source_file): Repackage macro-listing code as
	separate function.  Handle CGEN string macro expansion.
	(maybe_print_macro_listing): New function.

Index: tc.h
===================================================================
RCS file: /cvs/src/src/gas/tc.h,v
retrieving revision 1.3
diff -u -p -r1.3 tc.h
--- tc.h	2001/03/08 23:24:22	1.3
+++ tc.h	2001/04/02 16:23:06
@@ -1,6 +1,6 @@
 /* tc.h - target cpu dependent
 
-   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 2000
+   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 2000, 2001
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -53,7 +53,11 @@ int md_parse_option PARAMS ((int c, char
 void md_show_usage PARAMS ((FILE *));
 long md_pcrel_from PARAMS ((fixS * fixP));
 short tc_coff_fix2rtype PARAMS ((fixS * fixP));
+#if MD_ASSEMBLE_MACRO
+const char *md_assemble PARAMS ((char *str));
+#else
 void md_assemble PARAMS ((char *str));
+#endif
 void md_begin PARAMS ((void));
 #ifndef md_create_long_jump
 void md_create_long_jump PARAMS ((char *ptr, addressT from_addr,
Index: read.c
===================================================================
RCS file: /cvs/src/src/gas/read.c,v
retrieving revision 1.36
diff -u -p -r1.36 read.c
--- read.c	2001/03/28 17:24:01	1.36
+++ read.c	2001/04/02 16:23:08
@@ -1,6 +1,6 @@
 /* read.c - read a source file -
    Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
 This file is part of GAS, the GNU Assembler.
 
@@ -219,6 +219,7 @@ static int dwarf_file_string;
 #endif
 #endif
 
+static void maybe_print_macro_listing PARAMS ((void));
 static void cons_worker PARAMS ((int, int));
 static int scrub_from_string PARAMS ((char *, int));
 static void do_align PARAMS ((int, char *, int, int));
@@ -638,37 +639,7 @@ read_a_source_file (name)
 
 	  know (c != ' ');	/* No further leading whitespace.  */
 
-#ifndef NO_LISTING
-	  /* If listing is on, and we are expanding a macro, then give
-	     the listing code the contents of the expanded line.  */
-	  if (listing)
-	    {
-	      if ((listing & LISTING_MACEXP) && macro_nest > 0)
-		{
-		  char *copy;
-		  int len;
-
-		  /* Find the end of the current expanded macro line.  */
-		  for (s = input_line_pointer - 1; *s; ++s)
-		    if (is_end_of_line[(unsigned char) *s])
-		      break;
-
-		  /* Copy it for safe keeping.  Also give an indication of
-		     how much macro nesting is involved at this point.  */
-		  len = s - (input_line_pointer - 1);
-		  copy = (char *) xmalloc (len + macro_nest + 2);
-		  memset (copy, '>', macro_nest);
-		  copy[macro_nest] = ' ';
-		  memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
-		  copy[macro_nest + 1 + len] = '\0';
-
-		  /* Install the line with the listing facility.  */
-		  listing_newline (copy);
-		}
-	      else
-		listing_newline (NULL);
-	    }
-#endif
+	  maybe_print_macro_listing ();
 	  /* C is the 1st significant character.
 	     Input_line_pointer points after that character.  */
 	  if (is_name_beginner (c))
@@ -891,10 +862,40 @@ read_a_source_file (name)
 			    }
 			}
 
-		      md_assemble (s);	/* Assemble 1 instruction.  */
+#if MD_ASSEMBLE_MACRO
+		      {
+			/* If this is a hard insn, assemble it.  If it is a
+			   macro insn, expand it and return the expansion.
+			   (CGEN assemblers can have string macro insns.)  We
+			   don't handle string macros entirely within
+			   md_assemble because we want access to
+			   read_a_source_file's handling of pseudo-ops,
+			   labels, and macro listing.  We don't handle CGEN
+			   macro insn expansion via ordinary gas macro
+			   facilities because we want to choose the expansion
+			   based on operand constraints which are only
+			   available from md_assemble's operand parser.  */
+			const char *expand_str = md_assemble (s);
+			*input_line_pointer++ = c;
+			if (expand_str)
+			  {
+			    sb expand_sb;
+			    sb_new (&expand_sb);
+			    sb_add_string (&expand_sb, expand_str);
+			    free (expand_str);
+			    input_scrub_include_sb (&expand_sb,
+						    input_line_pointer, 1);
+			    sb_kill (&expand_sb);
+			    buffer_limit
+			      = input_scrub_next_buffer (&input_line_pointer);
 
+			    maybe_print_macro_listing ();
+			  }
+		      }
+#else
+		      md_assemble (s);	/* Assemble 1 instruction.  */
 		      *input_line_pointer++ = c;
-
+#endif
 		      /* We resume loop AFTER the end-of-line from
 			 this instruction.  */
 		    }
@@ -1091,6 +1092,44 @@ read_a_source_file (name)
   }
 #endif
 }
+
+static void
+maybe_print_macro_listing ()
+{
+#ifndef NO_LISTING
+  /* If listing is on, and we are expanding a macro, then give
+     the listing code the contents of the expanded line.  */
+  if (listing)
+    {
+      if ((listing & LISTING_MACEXP) && macro_nest > 0)
+	{
+	  char *copy;
+	  int len;
+	  char *s;
+
+	  /* Find the end of the current expanded macro line.  */
+	  for (s = input_line_pointer - 1; *s; ++s)
+	    if (is_end_of_line[(unsigned char) *s])
+	      break;
+
+	  /* Copy it for safe keeping.  Also give an indication of
+	     how much macro nesting is involved at this point.  */
+	  len = s - (input_line_pointer - 1);
+	  copy = (char *) xmalloc (len + macro_nest + 2);
+	  memset (copy, '>', macro_nest);
+	  copy[macro_nest] = ' ';
+	  memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
+	  copy[macro_nest + 1 + len] = '\0';
+
+	  /* Install the line with the listing facility.  */
+	  listing_newline (copy);
+	}
+      else
+	listing_newline (NULL);
+    }
+#endif
+}
+
 
 /* For most MRI pseudo-ops, the line actually ends at the first
    nonquoted space.  This function looks for that point, stuffs a null



More information about the Binutils mailing list