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