public inbox for cgen@sourceware.org
 help / color / mirror / Atom feed
* Re: PATCH: string-expansion macros
       [not found] <200103022358.QAA31874.cygnus.local.cgen@kayak.mcgary.org>
@ 2001-04-16 12:37 ` Frank Ch. Eigler
  2001-04-16 12:58   ` Greg McGary
  0 siblings, 1 reply; 6+ messages in thread
From: Frank Ch. Eigler @ 2001-04-16 12:37 UTC (permalink / raw)
  To: Greg McGary; +Cc: cgen

greg@mcgary.org (Greg McGary) writes:

: I have been sitting on this for almost 8 weeks now, waiting for some
: spare time to submit it.  [...]

Likewise, to give feedback. :-(

Overall, I like the extension.

: [...]
: I'd like to know why the old code tried to match macros before hard
: insns?  The reason I need to try hard insns before macros is that for
: my MIPS-like port, string macros catch cases that can't be handled by
: one insn, and implement a "virtual insn" that do things in 2 or 3 hard
: insns.  [...]

Yes, this makes sense in most cases, but methinks there are other
opposite cases also.  It would be nice to control ordering preference
by some attribute.

The biggest part that bothers me is that conditional messing-about
with the md_assemble function.  Rather than call it recursively like
this, I'd much rather see use of the gas sb (string-buffer) structure,
and treatment as expanded gas macro bodies.

- FChE

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: string-expansion macros
  2001-04-16 12:37 ` PATCH: string-expansion macros Frank Ch. Eigler
@ 2001-04-16 12:58   ` Greg McGary
  2001-04-16 13:18     ` Doug Evans
  0 siblings, 1 reply; 6+ messages in thread
From: Greg McGary @ 2001-04-16 12:58 UTC (permalink / raw)
  To: Frank Ch. Eigler; +Cc: cgen

fche@redhat.com (Frank Ch. Eigler) writes:

> : I'd like to know why the old code tried to match macros before hard
> : insns?  The reason I need to try hard insns before macros is that for
> : my MIPS-like port, string macros catch cases that can't be handled by
> : one insn, and implement a "virtual insn" that do things in 2 or 3 hard
> : insns.  [...]
>
> Yes, this makes sense in most cases, but methinks there are other
> opposite cases also.

Can you think of an example?

> It would be nice to control ordering preference
> by some attribute.

OK.  How about this: macro insns with attribute "POST" are forced
to match after real insns.

> The biggest part that bothers me is that conditional messing-about
> with the md_assemble function.

FYI, it didn't bother the gas maintainers.  That part of the patch was
approved a couple weeks ago.

> Rather than call it recursively like this,

Where do you see recursion?

> I'd much rather see use of the gas sb (string-buffer) structure,
> and treatment as expanded gas macro bodies.

That's what I'm doing.  Can you suggest a better way?

Greg

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: string-expansion macros
  2001-04-16 12:58   ` Greg McGary
@ 2001-04-16 13:18     ` Doug Evans
  2001-04-16 13:29       ` Greg McGary
  0 siblings, 1 reply; 6+ messages in thread
From: Doug Evans @ 2001-04-16 13:18 UTC (permalink / raw)
  To: Greg McGary; +Cc: Frank Ch. Eigler, cgen

Greg McGary writes:
 > fche@redhat.com (Frank Ch. Eigler) writes:
 > 
 > > : I'd like to know why the old code tried to match macros before hard
 > > : insns?  The reason I need to try hard insns before macros is that for
 > > : my MIPS-like port, string macros catch cases that can't be handled by
 > > : one insn, and implement a "virtual insn" that do things in 2 or 3 hard
 > > : insns.  [...]
 > >
 > > Yes, this makes sense in most cases, but methinks there are other
 > > opposite cases also.
 > 
 > Can you think of an example?

One way I think of macro insns is as being intercepts/wrappers
for real insns.  If you don't do the intercepts first, you ain't
gonna get the effect you want.

I think that's the way things should work,
and I wonder if needing to reverse it reveals a problem that
is best solved differently.

Note that macros were originally intended to support emitting
code rather than doing text transformation.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: string-expansion macros
  2001-04-16 13:18     ` Doug Evans
@ 2001-04-16 13:29       ` Greg McGary
  2001-04-16 13:41         ` Doug Evans
  0 siblings, 1 reply; 6+ messages in thread
From: Greg McGary @ 2001-04-16 13:29 UTC (permalink / raw)
  To: Doug Evans; +Cc: Frank Ch. Eigler, cgen

Doug Evans <dje@transmeta.com> writes:

> I think that's the way things should work,
> and I wonder if needing to reverse it reveals a problem that
> is best solved differently.

Intercepts are one use, whereas what I have implemented is a
"fallback" to be used only when a real insn won't match.  Both are
valid, IMO.  What needs to be done differently is to allow the
programmer to specify whether they want to intercept or if they want
to offer fallback.  Sounds like the least disruptive way to go is to
retain intercept semantics as the default, and allow an attribute to
specify fallback semantics.

Greg

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: string-expansion macros
  2001-04-16 13:29       ` Greg McGary
@ 2001-04-16 13:41         ` Doug Evans
  0 siblings, 0 replies; 6+ messages in thread
From: Doug Evans @ 2001-04-16 13:41 UTC (permalink / raw)
  To: Greg McGary; +Cc: Frank Ch. Eigler, cgen

Greg McGary writes:
 > Doug Evans <dje@transmeta.com> writes:
 > 
 > > I think that's the way things should work,
 > > and I wonder if needing to reverse it reveals a problem that
 > > is best solved differently.
 > 
 > Intercepts are one use, whereas what I have implemented is a
 > "fallback" to be used only when a real insn won't match.  Both are
 > valid, IMO.  What needs to be done differently is to allow the
 > programmer to specify whether they want to intercept or if they want
 > to offer fallback.  Sounds like the least disruptive way to go is to
 > retain intercept semantics as the default, and allow an attribute to
 > specify fallback semantics.

I don't have a problem with the attribute (well, I do, but
not a big enough of one to care).
I just wonder whether that's the best way to go.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* PATCH: string-expansion macros
@ 2001-03-02 15:59 Greg McGary
  0 siblings, 0 replies; 6+ messages in thread
From: Greg McGary @ 2001-03-02 15:59 UTC (permalink / raw)
  To: cgen

I have been sitting on this for almost 8 weeks now, waiting for some
spare time to submit it.  Well, I still have no spare time, but can't
in good conscience delay any longer.

I have several weeks experience using it in my port, and it works
fine.

A possibly controversial change is this:
	* opcodes/cgen-asm.c (build_asm_hash_table): Try to match hard
	insns before macros & aliases.
I'd like to know why the old code tried to match macros before hard
insns?  The reason I need to try hard insns before macros is that for
my MIPS-like port, string macros catch cases that can't be handled by
one insn, and implement a "virtual insn" that do things in 2 or 3 hard
insns.  E.g., hard insn for set-register accepts a 16-bit immediate
operand.  As a fallback, I have a string-macro that accepts a 32-bit
immediate and expands to two hard insns to set upper and lower
16-bits.  If the macro were tried first, a small constant actual
operand would certainly match the constraint of a 32-bit operand and
the 2-insn macro would expand before we tried the hard insn which
should match.  The only way that trying macros before hard insns could
work for me is with a more sophisticated 32-bit operand constraint
that only matches quantities that don't fit in 16 bits.

As an example of use, here are the "mov" insns for copying an
immediate into a register:

(dnmi moviwu "Move Immediate Word Unsigned" (NO-DIS)
      "mov $dest2,$uimm32"
      ("movhi %0,%1@h"
       "or %0,%1@l"))

(dnmi moviws "Move Immediate Word Signed" (NO-DIS)
      "mov $dest2,$simm32"
      ("movhi %0 %1@h"
       "or %0,%1@l"))

Here's a double-word add macro.  (I defined general register keywords
with `_next' suffix for making register pairs: $2 is register 2,
$2_next is register 3.)

(dnmi daddu "Add Double-word Unsigned" (NO-DIS)
      "daddu $dest,$src1,$src2"
      ("addu %0,%1,%2"
       "setltu %0_next,%0,%1"
       "addu %0_next,%0_next,%1_next"
       "addu %0_next,%0_next,%2_next"))

Comments?

Greg

This ChangeLog is unified.  At checkin time, I'll split it up among
the ChangeLog files in each of the component directories.

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

	* cgen/attr.scm (attr-builtin!): Add MACRO & STRING
	* cgen/minsn.scm (-minsn-parse-expansion): Allow list of strings.
	(-minsn-parse): Likewise.
	(define-full-minsn): Affix MACRO attr and STRING or ALIAS attr
	depending on type of expansion.
	* cgen/opc-itab.scm (-gen-ifield-decls) [cgen_fields]:
	New members op_starts and op_lengths.
	(opc-insert-handlers): New handler: insn-macro-string.
	(-gen-insn-opcode-entry): Wrap curlies around field which is now a union.
	(-gen-minsn-table-entry): Print proper string-macro entry.
	(-gen-minsn-macro-string-expansion): New function.
	(-gen-minsn-opcode-entry): Handle STRING macros.
	(-gen-macro-insn-table): Invert condition.  Test for STRING explicitly.
	* gas/read.c (read_a_source_file): Repackage macro-listing code.
	Handle CGEN string macro expansion.
	(maybe_print_macro_listing): New function.
	* gas/tc.h (md_assemble): Conditionalize return value on MD_ASSEMBLE_MACRO.
	* include/opcode/cgen.h (CGEN_OPCODE): wrap union around
	member `format', and add member `string' alongside.
	(CGEN_OPCODE_FORMAT): Traverse enclosing union.
	(CGEN_OPCODE_MACRO_STRING, CGEN_INSN_MACRO_STRING): New macros.
	* opcodes/cgen-asm.c (build_asm_hash_table): Try to match hard
	insns before macros & aliases.
	* opcodes/cgen-asm.in (parse_insn_normal): Remember starts &
	lengths of actual operands.
	* opcodes/cgen-ibld.in (insert_insn_normal): Return NULL if no errors.
	(insert_insn_macro_string): New function.

Index: cgen/attr.scm
===================================================================
RCS file: /cvs/src/src/cgen/attr.scm,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 attr.scm
--- attr.scm	2000/07/28 04:11:52	1.1.1.1
+++ attr.scm	2001/03/02 23:25:24
@@ -1,5 +1,5 @@
 ; Attributes.
-; Copyright (C) 2000 Red Hat, Inc.
+; Copyright (C) 2000, 2001 Red Hat, Inc.
 ; This file is part of CGEN.
 ; See file COPYING.CGEN for details.
 
@@ -893,11 +893,20 @@ Define an attribute, name/value pair lis
   (define-attr '(for keyword) '(type boolean) '(name PRIVATE))
 
   ; Attributes requiring fixed indices.
-  ; ALIAS is used for instructions that are aliases of more general insns.
-  ; ALIAS insns are ignored by the simulator.
+  ; MACRO insns are ignored by the simulator.
+  ; ALIAS is a 1:1 renaming (possibly omitting operands) of a real insn
+  ; STRING is an expansion into which we insert textual representation
+  ;   of operands and then reparse.
+  ; if neither ALIAS or STRING, expansion is a builder function.
   (define-attr '(for attr) '(type boolean) '(name INDEX) '(attrs META))
+  (define-attr '(for insn) '(type boolean) '(name MACRO)
+    '(comment "insn expands into something else")
+    '(attrs INDEX))
   (define-attr '(for insn) '(type boolean) '(name ALIAS)
-    '(comment "insn is an alias of another")
+    '(comment "insn is a macro that's a simple an alias of a real insn")
+    '(attrs INDEX))
+  (define-attr '(for insn) '(type boolean) '(name STRING)
+    '(comment "insn is a macro that expands into a string to be reparsed")
     '(attrs INDEX))
 
   *UNSPECIFIED*
Index: cgen/minsn.scm
===================================================================
RCS file: /cvs/src/src/cgen/minsn.scm,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 minsn.scm
--- minsn.scm	2000/07/28 04:11:52	1.1.1.1
+++ minsn.scm	2001/03/02 23:25:24
@@ -1,5 +1,5 @@
 ; Macro instruction definitions.
-; Copyright (C) 2000 Red Hat, Inc.
+; Copyright (C) 2000, 2001 Red Hat, Inc.
 ; This file is part of CGEN.
 ; See file COPYING.CGEN for details.
 
@@ -18,7 +18,10 @@
 ; description in the .cpu file.
 ; All arguments are in raw (non-evaluated) form.
 
-; ??? At present we only support macros that are aliases of one real insn.
+; ??? At present we only support macros that are
+;     1) aliases of one real insn
+;     2) and string-expansion.
+;     someday we might support a general insn builder mechanmsim as well.
 \f
 ; Object to describe a macro-insn.
 
@@ -57,13 +60,15 @@
 )
 
 ; Parse a macro-insn expansion description.
-; ??? At present we only support unconditional simple expansion.
 
 (define (-minsn-parse-expansion errtxt expn)
-  (if (not (form? expn))
-      (parse-error errtxt "invalid macro expansion" expn))
-  (if (not (eq? 'emit (car expn)))
-      (parse-error errtxt "invalid macro expansion, must be `(emit ...)'" expn))
+  (cond ((null? expn)
+	 (parse-error errtxt "empty macro expansion" expn))
+	((not (list? expn))
+	 (parse-error errtxt "invalid macro expansion" expn))
+	((not (or (eq? 'emit (car expn))
+		  (string? (car expn))))
+	 (parse-error errtxt "invalid macro expansion" expn)))
   expn
 )
 \f
@@ -76,26 +81,37 @@
 (define (-minsn-parse errtxt name comment attrs syntax expansions)
   (logit 2 "Processing macro-insn " name " ...\n")
 
-  (if (not (list? expansions))
-      (parse-error errtxt "invalid macro expansion list" expansions))
-
-  (let ((name (parse-name name errtxt))
-	(atlist-obj (atlist-parse attrs "cgen_minsn" errtxt)))
-
-    (if (keep-atlist? atlist-obj #f)
-
-	(let ((result (make <macro-insn>
-			name
-			(parse-comment comment errtxt)
-			atlist-obj
-			(parse-syntax syntax errtxt)
-			(map (lambda (e) (-minsn-parse-expansion errtxt e))
-			     expansions))))
-	  result)
-
-	(begin
-	  (logit 2 "Ignoring " name ".\n")
-	  #f)))
+  (if (cond ((not (list? expansions))
+	     (parse-error errtxt "invalid macro expansion: not a list" expansions)
+	     #f)
+	    ((not (list? (car expansions)))
+	     (parse-error errtxt "invalid macro expansion: not a list" expansions)
+	     #f)
+	    ((string? (caar expansions))
+	     (logit 2 "Parsing " name " as list-of-strings expansion.\n")
+	     #t)
+	    ((eq? 'emit (caar expansions))
+	     (logit 2 "Parsing " name " as emit expansion.\n")
+	     #t)
+	    (else
+	     (logit 2 "Ignoring " name ": unknown expansion.\n")
+	     #f))
+      (let ((name (parse-name name errtxt))
+	    (atlist-obj (atlist-parse attrs "cgen_minsn" errtxt)))
+
+	(if (keep-atlist? atlist-obj #f)
+	    (let ((result (make <macro-insn>
+			    name
+			    (parse-comment comment errtxt)
+			    atlist-obj
+			    (parse-syntax syntax errtxt)
+			    (map (lambda (e) (-minsn-parse-expansion errtxt e))
+				 expansions))))
+	      result)
+	    (begin
+	      (logit 2 "Ignoring " name ".\n")
+	      #f)))
+      #f)
 )
 
 ; Read a macro-insn description
@@ -152,7 +168,10 @@
   (if (eq? APPLICATION 'SIMULATOR)
       #f ; don't waste time if simulator
       (let ((m (-minsn-parse "define-full-minsn" name comment
-			     (cons 'ALIAS attrs)
+			     (cons 'MACRO
+				   (if (string? (car expansion))
+				       (cons 'STRING attrs)
+				       (cons 'ALIAS attrs)))
 			     syntax (list expansion))))
 	(if m
 	    (current-minsn-add! m))
Index: cgen/opc-itab.scm
===================================================================
RCS file: /cvs/src/src/cgen/opc-itab.scm,v
retrieving revision 1.2
diff -u -p -r1.2 opc-itab.scm
--- opc-itab.scm	2000/11/20 19:03:33	1.2
+++ opc-itab.scm	2001/03/02 23:25:25
@@ -1,5 +1,5 @@
 ; Opcode table support.
-; Copyright (C) 2000 Red Hat, Inc.
+; Copyright (C) 2000, 2001 Red Hat, Inc.
 ; This file is part of CGEN.
 
 ; Append code here to be run before insn parsing/etc.
@@ -47,6 +47,10 @@
    "struct cgen_fields\n{\n"
    ; A special member `length' is used to record the length.
    "  int length;\n"
+   ; Special members to hold operand strings for macro string expansion.
+   "  const char *op_starts[10];\n"
+   "  int op_lengths[10];\n"
+   "  const char *macro_string_expansion;\n"
    (string-map gen-ifield-value-decl (non-derived-ifields (current-ifld-list)))
    "};\n\n"
    )
@@ -237,7 +241,7 @@
 ; ??? It might be useful to define the handler in Scheme.  Later.
 
 (define opc-parse-handlers '((insn-normal)))
-(define opc-insert-handlers '((insn-normal)))
+(define opc-insert-handlers '((insn-normal) (insn-macro-string)))
 (define opc-extract-handlers '((insn-normal)))
 (define opc-print-handlers '((insn-normal)))
 
@@ -337,7 +341,7 @@
     "    " (gen-insn-handlers insn) ",\n"
     "    " (gen-syntax-entry "MNEM" "OP" (insn-syntax insn)) ",\n"
     ; ??? 'twould save space to put a pointer here and record format separately
-    "    " (gen-ifmt-entry insn) ", "
+    "    { " (gen-ifmt-entry insn) " }, "
     ;"0x" (number->string (insn-value insn) 16) ",\n"
     (gen-ivalue-entry insn) "\n"
     "  },\n"))
@@ -363,7 +367,7 @@ static const CGEN_OPCODE @arch@_cgen_ins
   /* Special null first entry.
      A `num' value of zero is thus invalid.
      Also, the special `invalid' insn resides here.  */
-  { { 0, 0, 0, 0 }, {{0}}, 0, {0}},\n"
+  { { 0, 0, 0, 0 }, {{0}}, {0}, {0}},\n"
 
      (lambda ()
        (string-write-map (lambda (insn)
@@ -494,18 +498,36 @@ static unsigned int dis_hash_insn PARAMS
   (gen-obj-sanitize
    minsn
    (string-list
-    "  /* " (minsn-syntax minsn) " */\n"
+    "/* " (minsn-syntax minsn) " */\n"
     "  {\n"
     "    "
     "-1, " ; macro-insns are not currently enumerated, no current need to
     "\"" (obj:name minsn) "\", "
-    "\"" (minsn-mnemonic minsn) "\",\n"
-    "    " (gen-syntax-entry "MNEM" "OP" (minsn-syntax minsn)) ",\n"
-    "    (PTR) & macro_" (gen-sym minsn) "_expansions[0],\n"
+    "\"" (minsn-mnemonic minsn) "\", -1,\n"
     "    "
-    (gen-obj-attr-defn 'minsn minsn all-attrs num-non-bools gen-insn-attr-mask)
-    "\n"
-    "  },\n"))
+    (gen-obj-attr-defn 'minsn minsn all-attrs num-non-bools gen-A-attr-mask)
+;;; (gen-bool-attrs (obj-atlist minsn) gen-A-attr-mask)
+    "\n  },\n"))
+)
+
+;;; macro string expansion is a list of strings, each representing
+;;; an assembler insn.  Combine them into a single C string with
+;;; newline separators and TAB prefixes, except that insns strings
+;;; beginning with "*" don't get TAB (this is used for labels that
+;;; want to begin in the first column).
+(define (-gen-minsn-macro-string-expansion expans)
+  (cond ((null? expans)
+	 "")
+	((string? expans)
+	 (string-append "\\\n"
+			(if (char=? (string-ref expans 0) #\*)
+			    (substring expans 1 (string-length expans))
+			    (string-append "\t" expans))
+			"\\n"))
+	((and (list? expans)
+	      (string? (car expans)))
+	 (string-append (-gen-minsn-macro-string-expansion (car expans))
+			(-gen-minsn-macro-string-expansion (cdr expans)))))
 )
 
 ; Return a macro-insn opcode table entry.
@@ -515,17 +537,21 @@ static unsigned int dis_hash_insn PARAMS
   (gen-obj-sanitize
    minsn
    (string-list
-    "  /* " (minsn-syntax minsn) " */\n"
+    "/* " (minsn-syntax minsn) " */\n"
     "  {\n"
-    "    "
-    "-1, " ; macro-insns are not currently enumerated, no current need to
-    "\"" (obj:name minsn) "\", "
-    "\"" (minsn-mnemonic minsn) "\",\n"
-    "    " (gen-syntax-entry "MNEM" "OP" (minsn-syntax minsn)) ",\n"
-    "    (PTR) & macro_" (gen-sym minsn) "_expansions[0],\n"
-    "    "
-    (gen-obj-attr-defn 'minsn minsn all-attrs num-non-bools gen-insn-attr-mask)
-    "\n"
+    "    { 0, 1, 0, 0 },\n"
+    ;; macro-insns are not currently enumerated, no current need to
+    "    " (gen-syntax-entry "MNEM" "OP" (minsn-syntax minsn)) ",\n    { "
+    (cond ((multi-insn? minsn)
+	   (string-append "& macro_" (gen-sym minsn) "_expansions[0]"))
+	  ((has-attr? minsn 'STRING)
+	   (string-append " \""
+			  (-gen-minsn-macro-string-expansion
+			   (car (minsn-expansions minsn)))
+			  "\""))
+	  (else
+	   (logit 2 "Unknown expansion type in -gen-minsn-opcode-entry\n")))
+    " }, { 0 }\n"
     "  },\n"))
 )
 
@@ -557,16 +583,17 @@ static unsigned int dis_hash_insn PARAMS
 					      minsn-list))))
      "#undef F\n\n"
      "/* Each non-simple macro entry points to an array of expansion possibilities.  */\n\n"
-     (lambda () 
+     (lambda ()
        (string-write-map (lambda (minsn)
-			   (if (has-attr? minsn 'ALIAS)
-			       ""
+			   ;; GKM FIXME: can a multi insn appear here???
+			   (if (multi-insn? minsn)
 			       (string-append
 				"static const CGEN_MINSN_EXPANSION macro_" (gen-sym minsn) "_expansions[] =\n"
 				"{\n"
 				(string-map -gen-miexpn-entry
 					    (minsn-expansions minsn))
-				"  { 0, 0 }\n};\n\n")))
+				"  { 0, 0 }\n};\n\n")
+			       ""))
 			 minsn-list))
      (gen-define-with-symcat "A(a) (1 << CGEN_INSN_" "a)")
      (gen-define-with-symcat "OPERAND(op) @ARCH@_OPERAND_" "op")
@@ -583,9 +610,11 @@ static const CGEN_IBASE @arch@_cgen_macr
        (string-write-map (lambda (minsn)
 			   (logit 3 "Generating macro-insn table entry for " (obj:name minsn) " ...\n")
 			   ; Simple macro-insns are emitted as aliases of real insns.
-			   (if (has-attr? minsn 'ALIAS)
-			       (gen-insn-table-entry minsn all-attrs num-non-bools)
-			       (-gen-minsn-table-entry minsn all-attrs num-non-bools)))
+			   (cond ((has-attr? minsn 'ALIAS)
+				  (gen-insn-table-entry minsn all-attrs num-non-bools))
+				 ((has-attr? minsn 'STRING)
+				  (-gen-minsn-table-entry minsn all-attrs num-non-bools))
+				 (else "")))
 			 minsn-list))
      "\
 };
Index: cgen/sim-decode.scm
===================================================================
RCS file: /cvs/src/src/cgen/sim-decode.scm,v
retrieving revision 1.4
diff -u -p -r1.4 sim-decode.scm
--- sim-decode.scm	2001/01/06 12:11:09	1.4
+++ sim-decode.scm	2001/03/02 23:25:25
@@ -433,7 +433,7 @@ void
    " extract_" (gen-sym sfmt) ":\n"
    "  {\n"
    "    const IDESC *idesc = &" IDESC-TABLE-VAR "[itype];\n"
-   (if (< (length (sfmt-iflds sfmt)) 0)
+   (if (> (length (sfmt-iflds sfmt)) 0)
        (string-append
 	"    CGEN_INSN_INT insn = "
 	(if (adata-integral-insn? CURRENT-ARCH)
Index: gas/read.c
===================================================================
RCS file: /cvs/src/src/gas/read.c,v
retrieving revision 1.32
diff -u -p -r1.32 read.c
--- read.c	2000/12/28 10:07:55	1.32
+++ read.c	2001/03/02 23:25:27
@@ -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,29 @@ read_a_source_file (name)
 			    }
 			}
 
-		      md_assemble (s);	/* Assemble 1 instruction.  */
+#if MD_ASSEMBLE_MACRO
+		      {
+			/* Assemble 1 instruction, or if a macro-insn,
+			   expand it and return the expansion.  */
+			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 +1081,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
Index: gas/tc.h
===================================================================
RCS file: /cvs/src/src/gas/tc.h,v
retrieving revision 1.2
diff -u -p -r1.2 tc.h
--- tc.h	2000/09/12 20:57:14	1.2
+++ tc.h	2001/03/02 23:25:28
@@ -1,6 +1,6 @@
 /* tc.h - target cpu dependent
 
-   Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -52,7 +52,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: include/opcode/cgen.h
===================================================================
RCS file: /cvs/src/src/include/opcode/cgen.h,v
retrieving revision 1.9
diff -u -p -r1.9 cgen.h
--- cgen.h	2001/02/02 23:04:39	1.9
+++ cgen.h	2001/03/02 23:25:28
@@ -904,13 +904,19 @@ typedef struct
 #define CGEN_OPCODE_SYNTAX(opc) (& (opc)->syntax)
 
   /* Format entry.  */
-  const CGEN_IFMT *format;
-#define CGEN_OPCODE_FORMAT(opc) ((opc)->format)
+  union {
+    /* hard insn.  */
+    const CGEN_IFMT *format;
+#define CGEN_OPCODE_FORMAT(opc) ((opc)->u.format)
 #define CGEN_OPCODE_MASK_BITSIZE(opc) CGEN_IFMT_MASK_LENGTH (CGEN_OPCODE_FORMAT (opc))
 #define CGEN_OPCODE_BITSIZE(opc) CGEN_IFMT_LENGTH (CGEN_OPCODE_FORMAT (opc))
 #define CGEN_OPCODE_IFLDS(opc) CGEN_IFMT_IFLDS (CGEN_OPCODE_FORMAT (opc))
+    /* 1:n macro insn.  */
+    const char *string;
+#define CGEN_OPCODE_MACRO_STRING(opc) ((opc)->u.string)
+  } u;
 
-  /* Instruction opcode value.  */
+  /* Instruction opcode value for hard insn.  */
   CGEN_IVALUE value;
 #define CGEN_OPCODE_VALUE(opc) (& (opc)->value)
 #define CGEN_OPCODE_BASE_VALUE(opc) (CGEN_OPCODE_VALUE (opc)->base_value)
@@ -1054,6 +1060,10 @@ extern int cgen_macro_insn_count PARAMS 
 /* Return value of base part of INSN.  */
 #define CGEN_INSN_BASE_VALUE(insn) \
   CGEN_OPCODE_BASE_VALUE (CGEN_INSN_OPCODE (insn))
+
+/* Return macro string expansion of INSN.  */
+#define CGEN_INSN_MACRO_STRING(insn) \
+  CGEN_OPCODE_MACRO_STRING (CGEN_INSN_OPCODE (insn))
 
 /* Standard way to test whether INSN is supported by MACH.
    MACH is one of enum mach_attr.
Index: opcodes/cgen-asm.c
===================================================================
RCS file: /cvs/src/src/opcodes/cgen-asm.c,v
retrieving revision 1.2
diff -u -p -r1.2 cgen-asm.c
--- cgen-asm.c	2000/07/26 22:45:49	1.2
+++ cgen-asm.c	2001/03/02 23:25:28
@@ -1,6 +1,6 @@
 /* CGEN generic assembler support code.
 
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils and GDB, the GNU debugger.
 
@@ -139,6 +139,13 @@ build_asm_hash_table (cd)
   asm_hash_table_entries = hash_entry_buf = (CGEN_INSN_LIST *)
     xmalloc (count * sizeof (CGEN_INSN_LIST));
 
+  /* Add compiled in macro-insns.  */
+
+  hash_entry_buf = hash_insn_array (cd, macro_insn_table->init_entries,
+				    macro_insn_table->num_init_entries,
+				    macro_insn_table->entry_size,
+				    asm_hash_table, hash_entry_buf);
+
   /* Add compiled in insns.
      Don't include the first one as it is a reserved entry.  */
   /* ??? It was the end of all hash chains, and also the special
@@ -150,23 +157,16 @@ build_asm_hash_table (cd)
 				    insn_table->entry_size,
 				    asm_hash_table, hash_entry_buf);
 
-  /* Add compiled in macro-insns.  */
+  /* Add runtime added macro-insns.  */
 
-  hash_entry_buf = hash_insn_array (cd, macro_insn_table->init_entries,
-				    macro_insn_table->num_init_entries,
-				    macro_insn_table->entry_size,
-				    asm_hash_table, hash_entry_buf);
+  hash_insn_list (cd, macro_insn_table->new_entries,
+		  asm_hash_table, hash_entry_buf);
 
   /* Add runtime added insns.
      Later added insns will be prefered over earlier ones.  */
 
   hash_entry_buf = hash_insn_list (cd, insn_table->new_entries,
 				   asm_hash_table, hash_entry_buf);
-
-  /* Add runtime added macro-insns.  */
-
-  hash_insn_list (cd, macro_insn_table->new_entries,
-		  asm_hash_table, hash_entry_buf);
 
   cd->asm_hash_table = asm_hash_table;
   cd->asm_hash_table_entries = asm_hash_table_entries;
Index: opcodes/cgen-asm.in
===================================================================
RCS file: /cvs/src/src/opcodes/cgen-asm.in,v
retrieving revision 1.4
diff -u -p -r1.4 cgen-asm.in
--- cgen-asm.in	2001/01/09 17:00:21	1.4
+++ cgen-asm.in	2001/03/02 23:25:29
@@ -70,6 +70,8 @@ parse_insn_normal (cd, insn, strp, field
   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
   const char *str = *strp;
   const char *errmsg;
+  const char **op_starts = fields->op_starts;
+  int *op_lengths = fields->op_lengths;
   const char *p;
   const CGEN_SYNTAX_CHAR_TYPE * syn;
 #ifdef CGEN_MNEMONIC_OPERANDS
@@ -149,14 +151,19 @@ parse_insn_normal (cd, insn, strp, field
 	}
 
       /* We have an operand of some sort.  */
+      *op_starts = str;
       errmsg = @arch@_cgen_parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
 					  &str, fields);
+      *op_lengths++ = (str - *op_starts++);
       if (errmsg)
 	return errmsg;
 
       /* Done with this operand, continue with next one.  */
       ++ syn;
     }
+
+  *op_starts = NULL;
+  *op_lengths = 0;
 
   /* If we're at the end of the syntax string, we're done.  */
   if (* syn == 0)
Index: opcodes/cgen-ibld.in
===================================================================
RCS file: /cvs/src/src/opcodes/cgen-ibld.in,v
retrieving revision 1.4
diff -u -p -r1.4 cgen-ibld.in
--- cgen-ibld.in	2001/01/09 17:00:21	1.4
+++ cgen-ibld.in	2001/03/02 23:25:29
@@ -34,6 +34,7 @@ along with this program; if not, write t
 #include "@prefix@-desc.h"
 #include "@prefix@-opc.h"
 #include "opintl.h"
+#include "libiberty.h"
 
 #undef min
 #define min(a,b) ((a) < (b) ? (a) : (b))
@@ -49,6 +50,9 @@ static const char * insert_normal
 static const char * insert_insn_normal
      PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *,
 	      CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
+static const char * insert_insn_macro_string
+     PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *,
+	      CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
 
 static int extract_normal
      PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
@@ -255,6 +259,86 @@ insert_insn_normal (cd, insn, fields, bu
 				       fields, buffer, pc);
       if (errmsg)
 	return errmsg;
+    }
+
+  return NULL;
+}
+
+/* Builder for string-expansion insn macros.
+   The result is an error message or NULL if success.  */
+
+static const char *
+insert_insn_macro_string (cd, insn, fields, buffer, pc)
+     CGEN_CPU_DESC cd;
+     const CGEN_INSN * insn;
+     CGEN_FIELDS * fields;
+     CGEN_INSN_BYTES_PTR buffer;
+     bfd_vma pc;
+{
+  const char *template = CGEN_INSN_MACRO_STRING (insn);
+  const char **op_starts = fields->op_starts;
+  int *op_lengths = fields->op_lengths;
+  char *expansion;
+  int length = 0;
+  const char *errmsg;
+
+  /* Use normal insertion in order to check operand constraints.  */
+  errmsg = insert_insn_normal (cd, insn, fields, buffer, pc);
+  if (errmsg)
+    return errmsg;
+  
+  for (;;)
+    {
+      char *insertion = strchr (template, '%');
+      if (insertion)
+	{
+	  int ic = insertion[1];
+	  length += insertion++ - template;
+	  if (ic == '%')
+	    length++;
+	  else if (isdigit (ic))
+	    length += op_lengths[ic - '0'];
+	  else
+	    return _("invalid positional parameter in macro string expansion");
+	  template = ++insertion;
+	}
+      else
+	{
+	  length += strlen (template);
+	  break;
+	}
+    }
+
+  fields->macro_string_expansion = expansion = xmalloc (length + 1);
+  template = CGEN_INSN_MACRO_STRING (insn);
+  for (;;)
+    {
+      char *insertion = strchr (template, '%');
+      if (insertion)
+	{
+	  int ic = insertion[1];
+	  int length = insertion++ - template;
+
+	  memcpy (expansion, template, length);
+	  expansion += length;
+	  template += length;
+	  if (ic == '%')
+	    *expansion++ = '%';
+	  else if (isdigit (ic))
+	    {
+	      ic -= '0';
+	      memcpy (expansion, op_starts[ic], op_lengths[ic]);
+	      expansion += op_lengths[ic];
+	    }
+	  else
+	    return _("invalid positional parameter in macro string expansion");
+	  template = ++insertion;
+	}
+      else
+	{
+	  strcpy (expansion, template);
+	  break;
+	}
     }
 
   return NULL;

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2001-04-16 13:41 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <200103022358.QAA31874.cygnus.local.cgen@kayak.mcgary.org>
2001-04-16 12:37 ` PATCH: string-expansion macros Frank Ch. Eigler
2001-04-16 12:58   ` Greg McGary
2001-04-16 13:18     ` Doug Evans
2001-04-16 13:29       ` Greg McGary
2001-04-16 13:41         ` Doug Evans
2001-03-02 15:59 Greg McGary

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).