]> git.pld-linux.org Git - packages/crossppc-binutils.git/blob - binutils-gasp.patch
- up
[packages/crossppc-binutils.git] / binutils-gasp.patch
1 diff -urNbB binutils-2.16.91.0.2.org/gas/Makefile.am binutils-2.16.91.0.2/gas/Makefile.am
2 --- binutils-2.16.91.0.2.org/gas/Makefile.am    2005-07-20 19:27:27.000000000 +0000
3 +++ binutils-2.16.91.0.2/gas/Makefile.am        2005-07-21 18:35:02.000000000 +0000
4 @@ -204,7 +204,7 @@
5         symbols.c \
6         write.c
7  
8 -CFILES = $(GAS_CFILES) itbl-ops.c
9 +CFILES = $(GAS_CFILES) gasp.c itbl-ops.c
10  
11  HFILES = \
12         as.h \
13 @@ -466,7 +466,8 @@
14  
15  # Note: GASP is now deprecated and has been removed.  It is still
16  # available in the CVS archive or older binutils releases if it is needed.
17 -noinst_PROGRAMS = as-new
18 +# ...and it is needed for few packages in distribution.
19 +noinst_PROGRAMS = as-new gasp-new
20  noinst_SCRIPTS = $(GDBINIT)
21  EXTRA_SCRIPTS = .gdbinit
22  
23 @@ -530,6 +531,10 @@
24         as.h asintl.h bignum.h bit_fix.h config.h emul.h expr.h flonum.h \
25         frags.h hash.h listing.h obj.h read.h symbols.h tc.h write.h
26  
27 +gasp_new_SOURCES = gasp.c macro.c sb.c hash.c
28 +gasp_new_LDADD = ../libiberty/libiberty.a $(INTLLIBS)
29 +gasp_new_DEPENDENCIES = ../libiberty/libiberty.a $(INTLDEPS)
30 +
31  EXPECT = expect
32  RUNTEST = runtest
33  RUNTESTFLAGS=
34 @@ -2508,6 +2513,8 @@
35    $(INCDIR)/obstack.h subsegs.h struc-symbol.h
36  write.o: write.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h \
37    output-file.h dwarf2dbg.h
38 +gasp.o: gasp.c $(INCDIR)/getopt.h $(INCDIR)/safe-ctype.h \
39 +  sb.h macro.h $(INCDIR)/xregex.h $(INCDIR)/xregex2.h
40  itbl-ops.o: itbl-ops.c itbl-ops.h $(INCDIR)/symcat.h
41  e-crisaout.o: $(srcdir)/config/e-crisaout.c $(INCDIR)/symcat.h \
42    emul-target.h
43 diff -urNbB binutils-2.16.91.0.2.org/gas/doc/Makefile.am binutils-2.16.91.0.2/gas/doc/Makefile.am
44 --- binutils-2.16.91.0.2.org/gas/doc/Makefile.am        2005-07-20 19:27:27.000000000 +0000
45 +++ binutils-2.16.91.0.2/gas/doc/Makefile.am    2005-07-21 18:31:04.000000000 +0000
46 @@ -15,7 +15,7 @@
47  
48  man_MANS = as.1
49  
50 -info_TEXINFOS = as.texinfo 
51 +info_TEXINFOS = as.texinfo gasp.texinfo
52  
53  asconfig.texi: $(CONFIG).texi
54         rm -f asconfig.texi
55 diff -urNbB binutils-2.16.91.0.2.org/gas/doc/gasp.texinfo binutils-2.16.91.0.2/gas/doc/gasp.texinfo
56 --- binutils-2.16.91.0.2.org/gas/doc/gasp.texinfo       1970-01-01 00:00:00.000000000 +0000
57 +++ binutils-2.16.91.0.2/gas/doc/gasp.texinfo   2005-07-21 18:31:04.000000000 +0000
58 @@ -0,0 +1,1456 @@
59 +\input texinfo               @c             -*- Texinfo -*-
60 +@setfilename gasp.info
61 +@c
62 +@c This file documents the assembly preprocessor "GASP"
63 +@c
64 +@c Copyright 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
65 +@c
66 +@c    Permission is granted to copy, distribute and/or modify this document
67 +@c    under the terms of the GNU Free Documentation License, Version 1.1
68 +@c    or any later version published by the Free Software Foundation;
69 +@c    with no Invariant Sections, with no Front-Cover Texts, and with no
70 +@c    Back-Cover Texts.  A copy of the license is included in the
71 +@c    section entitled "GNU Free Documentation License".
72 +
73 +@ifinfo
74 +@format
75 +START-INFO-DIR-ENTRY
76 +* gasp: (gasp).                     The GNU Assembler Preprocessor
77 +END-INFO-DIR-ENTRY
78 +@end format
79 +@end ifinfo
80 +
81 +@syncodeindex ky cp
82 +@syncodeindex fn cp
83 +
84 +@finalout
85 +@setchapternewpage odd
86 +@settitle GASP
87 +@titlepage
88 +@c FIXME boring title
89 +@title GASP, an assembly preprocessor
90 +@subtitle for GASP version 1
91 +@sp 1
92 +@subtitle March 1994
93 +@author Roland Pesch
94 +@page
95 +
96 +@tex
97 +{\parskip=0pt \hfill Cygnus Support\par
98 +}
99 +@end tex
100 +
101 +@vskip 0pt plus 1filll
102 +Copyright @copyright{} 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
103 +
104 +      Permission is granted to copy, distribute and/or modify this document
105 +      under the terms of the GNU Free Documentation License, Version 1.1
106 +      or any later version published by the Free Software Foundation;
107 +      with no Invariant Sections, with no Front-Cover Texts, and with no
108 +      Back-Cover Texts.  A copy of the license is included in the
109 +      section entitled "GNU Free Documentation License".
110 +
111 +@end titlepage
112 +
113 +@ifinfo
114 +Copyright @copyright{} 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
115 +
116 +@ignore
117 +Permission is granted to process this file through TeX and print the
118 +results, provided the printed document carries a copying permission
119 +notice identical to this one except for the removal of this paragraph
120 +(this paragraph not being relevant to the printed manual).
121 +@end ignore
122 +
123 +      Permission is granted to copy, distribute and/or modify this document
124 +      under the terms of the GNU Free Documentation License, Version 1.1
125 +      or any later version published by the Free Software Foundation;
126 +      with no Invariant Sections, with no Front-Cover Texts, and with no
127 +      Back-Cover Texts.  A copy of the license is included in the
128 +      section entitled "GNU Free Documentation License".
129 +
130 +
131 +@node Top
132 +@top GASP
133 +
134 +GASP is a preprocessor for assembly programs.
135 +
136 +This file describes version 1 of GASP.
137 +
138 +Steve Chamberlain wrote GASP; Roland Pesch wrote this manual.
139 +
140 +@menu
141 +* Overview::                    What is GASP?
142 +* Invoking GASP::               Command line options.
143 +* Commands::                    Preprocessor commands.
144 +* GNU Free Documentation License::  GNU Free Documentation License
145 +* Index::                       Index.
146 +@end menu
147 +@end ifinfo
148 +
149 +@node Overview
150 +@chapter What is GASP?
151 +
152 +The primary purpose of the @sc{gnu} assembler is to assemble the output of
153 +other programs---notably compilers.  When you have to hand-code
154 +specialized routines in assembly, that means the @sc{gnu} assembler is
155 +an unfriendly processor: it has no directives for macros, conditionals,
156 +or many other conveniences that you might expect.
157 +
158 +In some cases you can simply use the C preprocessor, or a generalized
159 +preprocessor like @sc{m4}; but this can be awkward, since none of these
160 +things are designed with assembly in mind.
161 +
162 +@sc{gasp} fills this need.  It is expressly designed to provide the
163 +facilities you need with hand-coded assembly code.  Implementing it as a
164 +preprocessor, rather than part of the assembler, allows the maximum
165 +flexibility: you can use it with hand-coded assembly, without paying a
166 +penalty of added complexity in the assembler you use for compiler
167 +output.
168 +
169 +@emph{Note} The use of @sc{gasp} has now been deprecated.  Anything
170 +that it could do can now be done by the macro facilities built into
171 +@sc{gas} itself.  At some point in the future the @sc{gasp} sources will
172 +be removed entirely from the binutils distribution.
173 +
174 +Here is a small example to give the flavor of @sc{gasp}.  This input to
175 +@sc{gasp}
176 +
177 +@cartouche
178 +@example
179 +        .MACRO  saveregs from=8 to=14
180 +count   .ASSIGNA \from
181 +        ! save r\from..r\to
182 +        .AWHILE  \&count LE \to
183 +        mov     r\&count,@@-sp
184 +count   .ASSIGNA  \&count + 1
185 +        .AENDW
186 +        .ENDM
187 +
188 +        saveregs from=12
189 +
190 +bar:    mov     #H'dead+10,r0
191 +foo     .SDATAC "hello"<10>
192 +        .END
193 +@end example
194 +@end cartouche
195 +
196 +@noindent
197 +generates this assembly program:
198 +
199 +@cartouche
200 +@example
201 +        ! save r12..r14
202 +        mov     r12,@@-sp
203 +        mov     r13,@@-sp
204 +        mov     r14,@@-sp
205 +
206 +bar:    mov     #57005+10,r0
207 +foo:    .byte   6,104,101,108,108,111,10
208 +@end example
209 +@end cartouche
210 +
211 +@node Invoking GASP
212 +@chapter Command Line Options
213 +
214 +@c FIXME!  Or is there a simpler way, calling from GAS option?
215 +The simplest way to use @sc{gasp} is to run it as a filter and assemble
216 +its output.  In Unix and its ilk, you can do this, for example:
217 +
218 +@c FIXME! GASP filename suffix convention?
219 +@example
220 +$ gasp prog.asm | as -o prog.o
221 +@end example
222 +
223 +Naturally, there are also a few command-line options to allow you to
224 +request variations on this basic theme.  Here is the full set of
225 +possibilities for the @sc{gasp} command line.
226 +
227 +@example
228 +gasp  [ -a | --alternate ]
229 +      [ -c @var{char} | --commentchar @var{char} ]
230 +      [ -d | --debug ]  [ -h | --help ] [ -M | --mri ]
231 +      [ -o @var{outfile} | --output @var{outfile} ]
232 +      [ -p | --print ]  [ -s | --copysource ]
233 +      [ -u | --unreasonable ]  [ -v | --version ]
234 +      @var{infile} @dots{}
235 +@end example
236 +
237 +@ftable @code
238 +@item @var{infile} @dots{}
239 +@c FIXME! Why not stdin as default infile?
240 +The input file names.  You must specify at least one input file; if you
241 +specify more, @sc{gasp} preprocesses them all, concatenating the output
242 +in the order you list the @var{infile} arguments.
243 +
244 +Mark the end of each input file with the preprocessor command
245 +@code{.END}.  @xref{Other Commands,, Miscellaneous commands}.
246 +
247 +@item -a
248 +@itemx --alternate
249 +Use alternative macro syntax.  @xref{Alternate,, Alternate macro
250 +syntax}, for a discussion of how this syntax differs from the default
251 +@sc{gasp} syntax.
252 +
253 +@cindex comment character, changing
254 +@cindex semicolon, as comment
255 +@cindex exclamation mark, as comment
256 +@cindex shriek, as comment
257 +@cindex bang, as comment
258 +@cindex @code{!} default comment char
259 +@cindex @code{;} as comment char
260 +@item -c '@var{char}'
261 +@itemx --commentchar '@var{char}'
262 +Use @var{char} as the comment character.  The default comment character
263 +is @samp{!}.  For example, to use a semicolon as the comment character,
264 +specify @w{@samp{-c ';'}} on the @sc{gasp} command line.  Since
265 +assembler command characters often have special significance to command
266 +shells, it is a good idea to quote or escape @var{char} when you specify
267 +a comment character.
268 +
269 +For the sake of simplicity, all examples in this manual use the default
270 +comment character @samp{!}.
271 +
272 +@item -d
273 +@itemx --debug
274 +Show debugging statistics.  In this version of @sc{gasp}, this option
275 +produces statistics about the string buffers that @sc{gasp} allocates
276 +internally.  For each defined buffersize @var{s}, @sc{gasp} shows the
277 +number of strings @var{n} that it allocated, with a line like this:
278 +
279 +@example
280 +strings size @var{s} : @var{n}
281 +@end example
282 +
283 +@noindent
284 +@sc{gasp} displays these statistics on the standard error stream, when
285 +done preprocessing.
286 +
287 +@item -h
288 +@itemx --help
289 +Display a summary of the @sc{gasp} command line options.
290 +
291 +@item -M
292 +@itemx --mri
293 +Use MRI compatibility mode.  Using this option causes @sc{gasp} to
294 +accept the syntax and pseudo-ops used by the Microtec Research
295 +@code{ASM68K} assembler.
296 +
297 +@item -o @var{outfile}
298 +@itemx --output @var{outfile}
299 +Write the output in a file called @var{outfile}.  If you do not use the
300 +@samp{-o} option, @sc{gasp} writes its output on the standard output
301 +stream.
302 +
303 +@item -p
304 +@itemx --print
305 +Print line numbers.  @sc{gasp} obeys this option @emph{only} if you also
306 +specify @samp{-s} to copy source lines to its output.  With @samp{-s
307 +-p}, @sc{gasp} displays the line number of each source line copied
308 +(immediately after the comment character at the beginning of the line).
309 +
310 +@item -s
311 +@itemx --copysource
312 +Copy the source lines to the output file.  Use this option
313 +to see the effect of each preprocessor line on the @sc{gasp} output.
314 +@sc{gasp} places a comment character (@samp{!} by default) at
315 +the beginning of each source line it copies, so that you can use this
316 +option and still assemble the result.
317 +
318 +@item -u
319 +@itemx --unreasonable
320 +Bypass ``unreasonable expansion'' limit.  Since you can define @sc{gasp}
321 +macros inside other macro definitions, the preprocessor normally
322 +includes a sanity check.  If your program requires more than 1,000
323 +nested expansions, @sc{gasp} normally exits with an error message.  Use
324 +this option to turn off this check, allowing unlimited nested
325 +expansions.
326 +
327 +@item -v
328 +@itemx --version
329 +Display the @sc{gasp} version number.
330 +@end ftable
331 +
332 +@node Commands
333 +@chapter Preprocessor Commands
334 +
335 +@sc{gasp} commands have a straightforward syntax that fits in well with
336 +assembly conventions.  In general, a command extends for a line, and may
337 +have up to three fields: an optional label, the command itself, and
338 +optional arguments to the command.  You can write commands in upper or
339 +lower case, though this manual shows them in upper case.  @xref{Syntax
340 +Details,, Details of the GASP syntax}, for more information.
341 +
342 +@menu
343 +* Conditionals::
344 +* Loops::
345 +* Variables::
346 +* Macros::
347 +* Data::
348 +* Listings::
349 +* Other Commands::
350 +* Syntax Details::
351 +* Alternate::
352 +@end menu
353 +
354 +@node Conditionals
355 +@section Conditional assembly
356 +
357 +The conditional-assembly directives allow you to include or exclude
358 +portions of an assembly depending on how a pair of expressions, or a
359 +pair of strings, compare.
360 +
361 +The overall structure of conditionals is familiar from many other
362 +contexts.  @code{.AIF} marks the start of a conditional, and precedes
363 +assembly for the case when the condition is true.   An optional
364 +@code{.AELSE} precedes assembly for the converse case, and an
365 +@code{.AENDI} marks the end of the condition.
366 +
367 +@c FIXME! Why doesn't -u turn off this check?
368 +You may nest conditionals up to a depth of 100; @sc{gasp} rejects
369 +nesting beyond that, because it may indicate a bug in your macro
370 +structure.
371 +
372 +@c FIXME! Why isn't there something like cpp's -D option?  Conditionals
373 +@c        would be much more useful if there were.
374 +Conditionals are primarily useful inside macro definitions, where you
375 +often need different effects depending on argument values.
376 +@xref{Macros,, Defining your own directives}, for details about defining
377 +macros.
378 +
379 +@ftable @code
380 +@item .AIF @var{expra} @var{cmp} @var{exprb}
381 +@itemx .AIF "@var{stra}" @var{cmp} "@var{strb}"
382 +
383 +The governing condition goes on the same line as the @code{.AIF}
384 +preprocessor command.  You may compare either two strings, or two
385 +expressions.
386 +
387 +When you compare strings, only two conditional @var{cmp} comparison
388 +operators are available: @samp{EQ} (true if @var{stra} and @var{strb}
389 +are identical), and @samp{NE} (the opposite).
390 +
391 +When you compare two expressions, @emph{both expressions must be
392 +absolute} (@pxref{Expressions,, Arithmetic expressions in GASP}).  You
393 +can use these @var{cmp} comparison operators with expressions:
394 +
395 +@ftable @code
396 +@item EQ
397 +Are @var{expra} and @var{exprb} equal?  (For strings, are @var{stra} and
398 +@var{strb} identical?)
399 +
400 +@item NE
401 +Are @var{expra} and @var{exprb} different?  (For strings, are @var{stra}
402 +and @var{strb} different?
403 +
404 +@item LT
405 +Is @var{expra} less than @var{exprb}?  (Not allowed for strings.)
406 +
407 +@item LE
408 +Is @var{expra} less than or equal to @var{exprb}?  (Not allowed for strings.)
409 +
410 +@item GT
411 +Is @var{expra} greater than @var{exprb}?  (Not allowed for strings.)
412 +
413 +@item GE
414 +Is @var{expra} greater than or equal to @var{exprb}?  (Not allowed for
415 +strings.)
416 +@end ftable
417 +
418 +@item .AELSE
419 +Marks the start of assembly code to be included if the condition fails.
420 +Optional, and only allowed within a conditional (between @code{.AIF} and
421 +@code{.AENDI}).
422 +
423 +@item .AENDI
424 +Marks the end of a conditional assembly.
425 +@end ftable
426 +
427 +@node Loops
428 +@section Repetitive sections of assembly
429 +
430 +Two preprocessor directives allow you to repeatedly issue copies of the
431 +same block of assembly code.
432 +
433 +@ftable @code
434 +@item .AREPEAT @var{aexp}
435 +@itemx .AENDR
436 +If you simply need to repeat the same block of assembly over and over a
437 +fixed number of times, sandwich one instance of the repeated block
438 +between @code{.AREPEAT} and @code{.AENDR}.  Specify the number of
439 +copies as @var{aexp} (which must be an absolute expression).  For
440 +example, this repeats two assembly statements three times in succession:
441 +
442 +@cartouche
443 +@example
444 +        .AREPEAT        3
445 +        rotcl   r2
446 +        div1    r0,r1
447 +        .AENDR
448 +@end example
449 +@end cartouche
450 +
451 +@item .AWHILE @var{expra} @var{cmp} @var{exprb}
452 +@itemx .AENDW
453 +@itemx .AWHILE @var{stra} @var{cmp} @var{strb}
454 +@itemx .AENDW
455 +To repeat a block of assembly depending on a conditional test, rather
456 +than repeating it for a specific number of times, use @code{.AWHILE}.
457 +@code{.AENDW} marks the end of the repeated block.  The conditional
458 +comparison works exactly the same way as for @code{.AIF}, with the same
459 +comparison operators (@pxref{Conditionals,, Conditional assembly}).
460 +
461 +Since the terms of the comparison must be absolute expression,
462 +@code{.AWHILE} is primarily useful within macros.  @xref{Macros,,
463 +Defining your own directives}.
464 +@end ftable
465 +
466 +@cindex loops, breaking out of
467 +@cindex breaking out of loops
468 +You can use the @code{.EXITM} preprocessor directive to break out of
469 +loops early (as well as to break out of macros).  @xref{Macros,,
470 +Defining your own directives}.
471 +
472 +@node Variables
473 +@section Preprocessor variables
474 +
475 +You can use variables in @sc{gasp} to represent strings, registers, or
476 +the results of expressions.
477 +
478 +You must distinguish two kinds of variables: 
479 +@enumerate
480 +@item
481 +Variables defined with @code{.EQU} or @code{.ASSIGN}.  To evaluate this
482 +kind of variable in your assembly output, simply mention its name.  For
483 +example, these two lines define and use a variable @samp{eg}:
484 +
485 +@cartouche
486 +@example
487 +eg     .EQU   FLIP-64
488 +       @dots{}
489 +       mov.l  eg,r0
490 +@end example
491 +@end cartouche
492 +
493 +@emph{Do not use} this kind of variable in conditional expressions or
494 +while loops; @sc{gasp} only evaluates these variables when writing
495 +assembly output.
496 +
497 +@item
498 +Variables for use during preprocessing.  You can define these
499 +with @code{.ASSIGNC} or @code{.ASSIGNA}.  To evaluate this
500 +kind of variable, write @samp{\&} before the variable name; for example,
501 +
502 +@cartouche
503 +@example
504 +opcit  .ASSIGNA  47
505 +       @dots{}
506 +       .AWHILE  \&opcit GT 0
507 +       @dots{}
508 +       .AENDW
509 +@end example
510 +@end cartouche
511 +
512 +@sc{gasp} treats macro arguments almost the same way, but to evaluate
513 +them you use the prefix @samp{\} rather than @samp{\&}.
514 +@xref{Macros,, Defining your own directives}.
515 +@end enumerate
516 +
517 +@ftable @code
518 +@item @var{pvar} .EQU @var{expr}
519 +@c FIXME!  Anything to beware of re GAS directive of same name?
520 +Assign preprocessor variable @var{pvar} the value of the expression
521 +@var{expr}.  There are no restrictions on redefinition; use @samp{.EQU}
522 +with the same @var{pvar} as often as you find it convenient.
523 +
524 +@item @var{pvar} .ASSIGN @var{expr}
525 +Almost the same as @code{.EQU}, save that you may not redefine
526 +@var{pvar} using @code{.ASSIGN} once it has a value.
527 +@c FIXME!!  Supposed to work this way, apparently, but on 9feb94 works
528 +@c          just like .EQU
529 +
530 +@item @var{pvar} .ASSIGNA @var{aexpr}
531 +Define a variable with a numeric value, for use during preprocessing.
532 +@var{aexpr} must be an absolute expression.  You can redefine variables
533 +with @code{.ASSIGNA} at any time.
534 +
535 +@item @var{pvar} .ASSIGNC "@var{str}"
536 +Define a variable with a string value, for use during preprocessing.
537 +You can redefine variables with @code{.ASSIGNC} at any time.
538 +
539 +@item @var{pvar} .REG (@var{register})
540 +Use @code{.REG} to define a variable that represents a register.  In
541 +particular, @var{register} is @emph{not evaluated} as an expression.
542 +You may use @code{.REG} at will to redefine register variables.
543 +@end ftable
544 +
545 +All these directives accept the variable name in the ``label'' position,
546 +that is at the left margin.  You may specify a colon after the variable
547 +name if you wish; the first example above could have started @samp{eg:}
548 +with the same effect.
549 +
550 +@c pagebreak makes for better aesthetics---ensures macro and expansion together
551 +@page
552 +@node Macros
553 +@section Defining your own directives
554 +
555 +The commands @code{.MACRO} and @code{.ENDM} allow you to define macros
556 +that generate assembly output.  You can use these macros with a syntax
557 +similar to built-in @sc{gasp} or assembler directives.  For example,
558 +this definition specifies a macro @code{SUM} that adds together a range of
559 +consecutive registers:
560 +
561 +@cartouche
562 +@example
563 +        .MACRO  SUM FROM=0, TO=9
564 +        ! \FROM \TO
565 +        mov     r\FROM,r10
566 +COUNT   .ASSIGNA        \FROM+1
567 +        .AWHILE \&COUNT LE \TO
568 +        add     r\&COUNT,r10
569 +COUNT   .ASSIGNA        \&COUNT+1
570 +        .AENDW
571 +        .ENDM
572 +@end example
573 +@end cartouche
574 +
575 +@noindent
576 +With that definition, @samp{SUM 0,5} generates this assembly output:
577 +
578 +@cartouche
579 +@example
580 +        ! 0 5
581 +        mov     r0,r10
582 +        add     r1,r10
583 +        add     r2,r10
584 +        add     r3,r10
585 +        add     r4,r10
586 +        add     r5,r10
587 +@end example
588 +@end cartouche
589 +
590 +@ftable @code
591 +@item .MACRO @var{macname}
592 +@itemx .MACRO @var{macname} @var{macargs} @dots{}
593 +Begin the definition of a macro called @var{macname}.  If your macro
594 +definition requires arguments, specify their names after the macro name,
595 +separated by commas or spaces.  You can supply a default value for any
596 +macro argument by following the name with @samp{=@var{deflt}}.  For
597 +example, these are all valid @code{.MACRO} statements:
598 +
599 +@table @code
600 +@item .MACRO COMM
601 +Begin the definition of a macro called @code{COMM}, which takes no
602 +arguments.
603 +
604 +@item .MACRO PLUS1 P, P1
605 +@itemx .MACRO PLUS1 P P1
606 +Either statement begins the definition of a macro called @code{PLUS1},
607 +which takes two arguments; within the macro definition, write
608 +@samp{\P} or @samp{\P1} to evaluate the arguments.
609 +
610 +@item .MACRO RESERVE_STR P1=0 P2
611 +Begin the definition of a macro called @code{RESERVE_STR}, with two
612 +arguments.  The first argument has a default value, but not the second.
613 +After the definition is complete, you can call the macro either as
614 +@samp{RESERVE_STR @var{a},@var{b}} (with @samp{\P1} evaluating to
615 +@var{a} and @samp{\P2} evaluating to @var{b}), or as @samp{RESERVE_STR
616 +,@var{b}} (with @samp{\P1} evaluating as the default, in this case
617 +@samp{0}, and @samp{\P2} evaluating to @var{b}).
618 +@end table
619 +
620 +When you call a macro, you can specify the argument values either by
621 +position, or by keyword.  For example, @samp{SUM 9,17} is equivalent to
622 +@samp{SUM TO=17, FROM=9}.  Macro arguments are preprocessor variables
623 +similar to the variables you define with @samp{.ASSIGNA} or
624 +@samp{.ASSIGNC}; in particular, you can use them in conditionals or for
625 +loop control.  (The only difference is the prefix you write to evaluate
626 +the variable: for a macro argument, write @samp{\@var{argname}}, but for
627 +a preprocessor variable, write @samp{\&@var{varname}}.)
628 +
629 +@item @var{name} .MACRO
630 +@itemx @var{name} .MACRO ( @var{macargs} @dots{} )
631 +@c FIXME check: I think no error _and_ no args recognized if I use form
632 +@c       NAME  .MACRO   ARG ARG
633 +An alternative form of introducing a macro definition: specify the macro
634 +name in the label position, and the arguments (if any) between
635 +parentheses after the name.  Defaulting rules and usage work the same
636 +way as for the other macro definition syntax.
637 +
638 +@item .ENDM
639 +Mark the end of a macro definition.
640 +
641 +@item .EXITM
642 +Exit early from the current macro definition, @code{.AREPEAT} loop, or
643 +@code{.AWHILE} loop.
644 +
645 +@cindex number of macros executed
646 +@cindex macros, count executed
647 +@item \@@
648 +@sc{gasp} maintains a counter of how many macros it has
649 +executed in this pseudo-variable; you can copy that number to your
650 +output with @samp{\@@}, but @emph{only within a macro definition}.
651 +
652 +@item LOCAL @var{name} [ , @dots{} ]
653 +@emph{Warning: @code{LOCAL} is only available if you select ``alternate
654 +macro syntax'' with @samp{-a} or @samp{--alternate}.}  @xref{Alternate,,
655 +Alternate macro syntax}.
656 +
657 +Generate a string replacement for each of the @var{name} arguments, and
658 +replace any instances of @var{name} in each macro expansion.  The
659 +replacement string is unique in the assembly, and different for each
660 +separate macro expansion.  @code{LOCAL} allows you to write macros that
661 +define symbols, without fear of conflict between separate macro expansions.
662 +@end ftable
663 +
664 +@node Data
665 +@section Data output
666 +
667 +In assembly code, you often need to specify working areas of memory;
668 +depending on the application, you may want to initialize such memory or
669 +not.  @sc{gasp} provides preprocessor directives to help you avoid
670 +repetitive coding for both purposes.
671 +
672 +You can use labels as usual to mark the data areas.
673 +
674 +@menu
675 +* Initialized::
676 +* Uninitialized::
677 +@end menu
678 +
679 +@node Initialized
680 +@subsection Initialized data
681 +
682 +These are the @sc{gasp} directives for initialized data, and the standard
683 +@sc{gnu} assembler directives they expand to:
684 +
685 +@ftable @code
686 +@item .DATA @var{expr}, @var{expr}, @dots{}
687 +@itemx .DATA.B @var{expr}, @var{expr}, @dots{}
688 +@itemx .DATA.W @var{expr}, @var{expr}, @dots{}
689 +@itemx .DATA.L @var{expr}, @var{expr}, @dots{}
690 +Evaluate arithmetic expressions @var{expr}, and emit the corresponding
691 +@code{as} directive (labelled with @var{lab}).  The unqualified
692 +@code{.DATA} emits @samp{.long}; @code{.DATA.B} emits @samp{.byte};
693 +@code{.DATA.W} emits @samp{.short}; and @code{.DATA.L} emits
694 +@samp{.long}.
695 +
696 +For example, @samp{foo .DATA 1,2,3} emits @samp{foo: .long 1,2,3}.
697 +
698 +@item .DATAB @var{repeat}, @var{expr}
699 +@itemx .DATAB.B @var{repeat}, @var{expr}
700 +@itemx .DATAB.W @var{repeat}, @var{expr}
701 +@itemx .DATAB.L @var{repeat}, @var{expr}
702 +@c FIXME! Looks like gasp accepts and ignores args after 2nd.
703 +Make @code{as} emit @var{repeat} copies of the value of the expression
704 +@var{expr} (using the @code{as} directive @code{.fill}).
705 +@samp{.DATAB.B} repeats one-byte values; @samp{.DATAB.W} repeats
706 +two-byte values; and @samp{.DATAB.L} repeats four-byte values.
707 +@samp{.DATAB} without a suffix repeats four-byte values, just like
708 +@samp{.DATAB.L}.
709 +
710 +@c FIXME! Allowing zero might be useful for edge conditions in macros.
711 +@var{repeat} must be an absolute expression with a positive value.
712 +
713 +@item .SDATA "@var{str}" @dots{}
714 +String data.  Emits a concatenation of bytes, precisely as you specify
715 +them (in particular, @emph{nothing is added to mark the end} of the
716 +string).  @xref{Constants,, String and numeric constants}, for details
717 +about how to write strings.  @code{.SDATA} concatenates multiple
718 +arguments, making it easy to switch between string representations.  You
719 +can use commas to separate the individual arguments for clarity, if you
720 +choose.
721 +
722 +@item .SDATAB @var{repeat}, "@var{str}" @dots{}
723 +Repeated string data.  The first argument specifies how many copies of
724 +the string to emit; the remaining arguments specify the string, in the
725 +same way as the arguments to @code{.SDATA}.
726 +
727 +@item .SDATAZ "@var{str}" @dots{}
728 +Zero-terminated string data.  Just like @code{.SDATA}, except that
729 +@code{.SDATAZ} writes a zero byte at the end of the string.
730 +
731 +@item .SDATAC "@var{str}" @dots{}
732 +Count-prefixed string data.  Just like @code{.SDATA}, except that
733 +@sc{gasp} precedes the string with a leading one-byte count.  For
734 +example, @samp{.SDATAC "HI"} generates @samp{.byte 2,72,73}.  Since the
735 +count field is only one byte, you can only use @code{.SDATAC} for
736 +strings less than 256 bytes in length.
737 +@end ftable
738 +
739 +@node Uninitialized
740 +@subsection Uninitialized data
741 +
742 +@c FIXME!  .space different on some platforms, notably HPPA.  Config?
743 +Use the @code{.RES}, @code{.SRES}, @code{.SRESC}, and @code{.SRESZ}
744 +directives to reserve memory and leave it uninitialized.  @sc{gasp}
745 +resolves these directives to appropriate calls of the @sc{gnu}
746 +@code{as} @code{.space} directive.
747 +
748 +@ftable @code
749 +@item .RES @var{count}
750 +@itemx .RES.B @var{count}
751 +@itemx .RES.W @var{count}
752 +@itemx .RES.L @var{count}
753 +Reserve room for @var{count} uninitialized elements of data.  The
754 +suffix specifies the size of each element: @code{.RES.B} reserves
755 +@var{count} bytes, @code{.RES.W} reserves @var{count} pairs of bytes,
756 +and @code{.RES.L} reserves @var{count} quartets.  @code{.RES} without a
757 +suffix is equivalent to @code{.RES.L}.
758 +
759 +@item .SRES @var{count}
760 +@itemx .SRES.B @var{count}
761 +@itemx .SRES.W @var{count}
762 +@itemx .SRES.L @var{count}
763 +@c FIXME!  This is boring.  Shouldn't it at least have a different
764 +@c         default size?  (e.g. the "S" suggests "string", for which .B
765 +@c         would be more appropriate)
766 +@code{.SRES} is a synonym for @samp{.RES}.
767 +
768 +@item .SRESC @var{count}
769 +@itemx .SRESC.B @var{count}
770 +@itemx .SRESC.W @var{count}
771 +@itemx .SRESC.L @var{count}
772 +Like @code{.SRES}, but reserves space for @code{@var{count}+1} elements.
773 +
774 +@item .SRESZ @var{count}
775 +@itemx .SRESZ.B @var{count}
776 +@itemx .SRESZ.W @var{count}
777 +@itemx .SRESZ.L @var{count}
778 +Like @code{.SRES}, but reserves space for @code{@var{count}+1} elements.
779 +@end ftable
780 +
781 +@node Listings
782 +@section Assembly listing control
783 +
784 +The @sc{gasp} listing-control directives correspond to
785 +related @sc{gnu} @code{as} directives.
786 +
787 +@ftable @code
788 +@item .PRINT LIST
789 +@itemx .PRINT NOLIST
790 +Print control.  This directive emits the @sc{gnu} @code{as} directive
791 +@code{.list} or @code{.nolist}, according to its argument.  @xref{List,,
792 +@code{.list}, as.info, Using as}, for details on how these directives
793 +interact.
794 +
795 +@item .FORM LIN=@var{ln}
796 +@itemx .FORM COL=@var{cols}
797 +@itemx .FORM LIN=@var{ln} COL=@var{cols}
798 +Specify the page size for assembly listings: @var{ln} represents the
799 +number of lines, and @var{cols} the number of columns.  You may specify
800 +either page dimension independently, or both together.  If you do not
801 +specify the number of lines, @sc{gasp} assumes 60 lines; if you do not
802 +specify the number of columns, @sc{gasp} assumes 132 columns.
803 +(Any values you may have specified in previous instances of @code{.FORM}
804 +do @emph{not} carry over as defaults.)  Emits the @code{.psize}
805 +assembler directive.
806 +
807 +@item .HEADING @var{string}
808 +Specify @var{string} as the title of your assembly listings.  Emits
809 +@samp{.title "@var{string}"}.
810 +
811 +@item .PAGE
812 +Force a new page in assembly listings.  Emits @samp{.eject}.
813 +@end ftable
814 +
815 +@node Other Commands
816 +@section Miscellaneous commands
817 +
818 +@ftable @code
819 +@item .ALTERNATE
820 +Use the alternate macro syntax henceforth in the assembly.
821 +@xref{Alternate,, Alternate macro syntax}.
822 +
823 +@item .ORG
824 +@c FIXME!  This is very strange, since _GAS_ understands .org
825 +This command is recognized, but not yet implemented.  @sc{gasp}
826 +generates an error message for programs that use @code{.ORG}.
827 +
828 +@item .RADIX @var{s}
829 +@c FIXME no test cases in testsuite/gasp
830 +@sc{gasp} understands numbers in any of base two, eight, ten, or
831 +sixteen.  You can encode the base explicitly in any numeric constant
832 +(@pxref{Constants,, String and numeric constants}).  If you write
833 +numbers without an explicit indication of the base, the most recent
834 +@samp{.RADIX @var{s}} command determines how they are interpreted.
835 +@var{s} is a single letter, one of the following:
836 +
837 +@table @code
838 +@item .RADIX B
839 +Base 2.
840 +
841 +@item .RADIX Q
842 +Base 8.
843 +
844 +@item .RADIX D
845 +Base 10.  This is the original default radix.
846 +
847 +@item .RADIX H
848 +Base 16.
849 +@end table
850 +
851 +You may specify the argument @var{s} in lower case (any of @samp{bqdh})
852 +with the same effects.
853 +
854 +@item .EXPORT @var{name}
855 +@itemx .GLOBAL @var{name}
856 +@c FIXME! No test cases in testsuite/gasp
857 +Declare @var{name} global (emits @samp{.global @var{name}}).  The two
858 +directives are synonymous.
859 +
860 +@item .PROGRAM
861 +No effect: @sc{gasp} accepts this directive, and silently ignores it.
862 +
863 +@item .END
864 +Mark end of each preprocessor file.  @sc{gasp} issues a warning if it
865 +reaches end of file without seeing this command.
866 +
867 +@item .INCLUDE "@var{str}"
868 +Preprocess the file named by @var{str}, as if its contents appeared
869 +where the @code{.INCLUDE} directive does.  @sc{gasp} imposes a maximum
870 +limit of 30 stacked include files, as a sanity check.
871 +@c FIXME!  Why is include depth not affected by -u?
872 +
873 +@item .ALIGN @var{size}
874 +@c FIXME! Why is this not utterly pointless?
875 +Evaluate the absolute expression @var{size}, and emit the assembly
876 +instruction @samp{.align @var{size}} using the result.
877 +@end ftable
878 +
879 +@node Syntax Details
880 +@section Details of the GASP syntax
881 +
882 +Since @sc{gasp} is meant to work with assembly code, its statement
883 +syntax has no surprises for the assembly programmer.
884 +
885 +@cindex whitespace
886 +@emph{Whitespace} (blanks or tabs; @emph{not} newline) is partially
887 +significant, in that it delimits up to three fields in a line.  The
888 +amount of whitespace does not matter; you may line up fields in separate
889 +lines if you wish, but @sc{gasp} does not require that.
890 +
891 +@cindex fields of @sc{gasp} source line
892 +@cindex label field
893 +The @emph{first field}, an optional @dfn{label}, must be flush left in a
894 +line (with no leading whitespace) if it appears at all.  You may use a
895 +colon after the label if you wish; @sc{gasp} neither requires the colon
896 +nor objects to it (but will not include it as part of the label name).
897 +
898 +@cindex directive field
899 +The @emph{second field}, which must appear after some whitespace,
900 +contains a @sc{gasp} or assembly @dfn{directive}.
901 +
902 +@cindex argument fields
903 +Any @emph{further fields} on a line are @dfn{arguments} to the
904 +directive; you can separate them from one another using either commas or
905 +whitespace.
906 +
907 +@menu
908 +* Markers::
909 +* Constants::
910 +* Symbols::
911 +* Expressions::
912 +* String Builtins::
913 +@end menu
914 +
915 +@node Markers
916 +@subsection Special syntactic markers
917 +
918 +@sc{gasp} recognizes a few special markers: to delimit comments, to
919 +continue a statement on the next line, to separate symbols from other
920 +characters, and to copy text to the output literally.  (One other
921 +special marker, @samp{\@@}, works only within macro definitions;
922 +@pxref{Macros,, Defining your own directives}.)
923 +
924 +@cindex comments
925 +The trailing part of any @sc{gasp} source line may be a @dfn{comment}.
926 +A comment begins with the first unquoted comment character (@samp{!} by
927 +default), or an escaped or doubled comment character (@samp{\!} or
928 +@samp{!!} by default), and extends to the end of a line.  You can
929 +specify what comment character to use with the @samp{-c} option
930 +(@pxref{Invoking GASP,, Command Line Options}).  The two kinds of
931 +comment markers lead to slightly different treatment:
932 +
933 +@table @code
934 +@item !
935 +A single, un-escaped comment character generates an assembly comment in
936 +the @sc{gasp} output.  @sc{gasp} evaluates any preprocessor variables
937 +(macro arguments, or variables defined with @code{.ASSIGNA} or
938 +@code{.ASSIGNC}) present.  For example, a macro that begins like this
939 +
940 +@example
941 +        .MACRO  SUM FROM=0, TO=9
942 +        ! \FROM \TO
943 +@end example
944 +
945 +@noindent
946 +issues as the first line of output a comment that records the
947 +values you used to call the macro.
948 +
949 +@c comments, preprocessor-only
950 +@c preprocessor-only comments
951 +@c GASP-only comments
952 +@item \!
953 +@itemx !!
954 +Either an escaped comment character, or a double comment character,
955 +marks a @sc{gasp} source comment.  @sc{gasp} does not copy such comments
956 +to the assembly output.
957 +@end table
958 +
959 +@cindex continuation character
960 +@kindex +
961 +To @emph{continue a statement} on the next line of the file, begin the
962 +second line with the character @samp{+}.
963 +
964 +@cindex literal copy to output
965 +@cindex copying literally to output
966 +@cindex preprocessing, avoiding
967 +@cindex avoiding preprocessing
968 +Occasionally you may want to prevent @sc{gasp} from preprocessing some
969 +particular bit of text.  To @emph{copy literally} from the @sc{gasp}
970 +source to its output, place @samp{\(} before the string to copy, and
971 +@samp{)} at the end.  For example, write @samp{\(\!)} if you need the
972 +characters @samp{\!} in your assembly output.
973 +
974 +@cindex symbol separator
975 +@cindex text, separating from symbols
976 +@cindex symbols, separating from text
977 +To @emph{separate a preprocessor variable} from text to appear
978 +immediately after its value, write a single quote (@code{'}).  For
979 +example, @samp{.SDATA "\P'1"} writes a string built by concatenating the
980 +value of @code{P} and the digit @samp{1}.  (You cannot achieve this by
981 +writing just @samp{\P1}, since @samp{P1} is itself a valid name for a
982 +preprocessor variable.)
983 +
984 +@node Constants
985 +@subsection String and numeric constants
986 +
987 +There are two ways of writing @dfn{string constants} in @sc{gasp}: as
988 +literal text, and by numeric byte value.  Specify a string literal
989 +between double quotes (@code{"@var{str}"}).  Specify an individual
990 +numeric byte value as an absolute expression between angle brackets
991 +(@code{<@var{expr}>}.  Directives that output strings allow you to
992 +specify any number of either kind of value, in whatever order is
993 +convenient, and concatenate the result.  (Alternate syntax mode
994 +introduces a number of alternative string notations; @pxref{Alternate,,
995 +Alternate macro syntax}.)
996 +
997 +@c Details of numeric notation, e.g. base prefixes
998 +You can write @dfn{numeric constants} either in a specific base, or in
999 +whatever base is currently selected (either 10, or selected by the most
1000 +recent @code{.RADIX}).
1001 +
1002 +To write a number in a @emph{specific base}, use the pattern
1003 +@code{@var{s}'@var{ddd}}: a base specifier character @var{s}, followed
1004 +by a single quote followed by digits @var{ddd}.  The base specifier
1005 +character matches those you can specify with @code{.RADIX}: @samp{B} for
1006 +base 2, @samp{Q} for base 8, @samp{D} for base 10, and @samp{H} for base
1007 +16.  (You can write this character in lower case if you prefer.)
1008 +
1009 +You can write floating point constants using the same syntax recognised
1010 +by GAS @ref{Flonums,,Flonums,as,The GNU Assembler.}.  A constraint is
1011 +that these constants will be interpreted as decimal values irrespective
1012 +of the currently selected base.
1013 +
1014 +@c FIXME! What are rules for recognizing number in deflt base?  Whatever
1015 +@c        is left over after parsing other things??
1016 +
1017 +@node Symbols
1018 +@subsection Symbols
1019 +
1020 +@sc{gasp} recognizes symbol names that start with any alphabetic character,
1021 +@samp{_}, or @samp{$}, and continue with any of the same characters or
1022 +with digits.  Label names follow the same rules.
1023 +
1024 +@node Expressions
1025 +@subsection Arithmetic expressions in GASP
1026 +
1027 +@cindex absolute expressions
1028 +@cindex relocatable expressions
1029 +There are two kinds of expressions, depending on their result:
1030 +@dfn{absolute} expressions, which resolve to a constant (that is, they
1031 +do not involve any values unknown to @sc{gasp}), and @dfn{relocatable}
1032 +expressions, which must reduce to the form
1033 +
1034 +@example
1035 +@var{addsym}+@var{const}-@var{subsym}
1036 +@end example
1037 +
1038 +@noindent
1039 +where @var{addsym} and @var{subsym} are assembly symbols of unknown
1040 +value, and @var{const} is a constant.
1041 +
1042 +Arithmetic for @sc{gasp} expressions follows very similar rules to C.
1043 +You can use parentheses to change precedence; otherwise, arithmetic
1044 +primitives have decreasing precedence in the order of the following
1045 +list.
1046 +
1047 +@enumerate
1048 +@item
1049 +Single-argument @code{+} (identity), @code{-} (arithmetic opposite), or
1050 +@code{~} (bitwise negation).  @emph{The argument must be an absolute
1051 +expression.}
1052 +
1053 +@item
1054 +@code{*} (multiplication) and @code{/} (division).  @emph{Both arguments
1055 +must be absolute expressions.}
1056 +
1057 +@item
1058 +@code{+} (addition) and @code{-} (subtraction).  @emph{At least one argument
1059 +must be absolute.}
1060 +@c FIXME!  Actually, subtraction doesn't check for this.
1061 +
1062 +@item
1063 +@code{&} (bitwise and).  @emph{Both arguments must be absolute.}
1064 +
1065 +@item
1066 +@c FIXME!  I agree ~ is a better notation than ^ for xor, but is the
1067 +@c         improvement worth differing from C?
1068 +@code{|} (bitwise or) and @code{~} (bitwise exclusive or; @code{^} in
1069 +C).  @emph{Both arguments must be absolute.}
1070 +@end enumerate
1071 +
1072 +@node String Builtins
1073 +@subsection String primitives
1074 +
1075 +You can use these primitives to manipulate strings (in the argument
1076 +field of @sc{gasp} statements):
1077 +
1078 +@ftable @code
1079 +@item .LEN("@var{str}")
1080 +Calculate the length of string @code{"@var{str}"}, as an absolute
1081 +expression.  For example, @samp{.RES.B .LEN("sample")} reserves six
1082 +bytes of memory.
1083 +
1084 +@item .INSTR("@var{string}", "@var{seg}", @var{ix})
1085 +Search for the first occurrence of @var{seg} after position @var{ix} of
1086 +@var{string}.  For example, @samp{.INSTR("ABCDEFG", "CDE", 0)} evaluates
1087 +to the absolute result @code{2}.
1088 +
1089 +The result is @code{-1} if @var{seg} does not occur in @var{string}
1090 +after position @var{ix}.
1091 +
1092 +@item .SUBSTR("@var{string}",@var{start},@var{len})
1093 +The substring of @var{string} beginning at byte number @var{start} and
1094 +extending for @var{len} bytes.
1095 +@end ftable
1096 +
1097 +@node Alternate
1098 +@section Alternate macro syntax
1099 +
1100 +If you specify @samp{-a} or @samp{--alternate} on the @sc{gasp} command
1101 +line, the preprocessor uses somewhat different syntax.  This syntax is
1102 +reminiscent of the syntax of Phar Lap macro assembler, but it
1103 +is @emph{not} meant to be a full emulation of Phar Lap or similar
1104 +assemblers.  In particular, @sc{gasp} does not support directives such
1105 +as @code{DB} and @code{IRP}, even in alternate syntax mode.
1106 +
1107 +In particular, @samp{-a} (or @samp{--alternate}) elicits these
1108 +differences:
1109 +
1110 +@table @emph
1111 +@item Preprocessor directives
1112 +You can use @sc{gasp} preprocessor directives without a leading @samp{.}
1113 +dot.  For example, you can write @samp{SDATA} with the same effect as
1114 +@samp{.SDATA}.
1115 +
1116 +@item LOCAL
1117 +One additional directive, @code{LOCAL}, is available.  @xref{Macros,,
1118 +Defining your own directives}, for an explanation of how to use
1119 +@code{LOCAL}.
1120 +
1121 +@need 2000
1122 +@item String delimiters
1123 +You can write strings delimited in these other ways besides
1124 +@code{"@var{string}"}:
1125 +
1126 +@table @code
1127 +@item '@var{string}'
1128 +You can delimit strings with single-quote charaters.
1129 +
1130 +@item <@var{string}>
1131 +You can delimit strings with matching angle brackets.
1132 +@end table
1133 +
1134 +@item single-character string escape
1135 +To include any single character literally in a string (even if the
1136 +character would otherwise have some special meaning), you can prefix the
1137 +character with @samp{!} (an exclamation mark).  For example, you can
1138 +write @samp{<4.3 !> 5.4!!>} to get the literal text @samp{4.3 > 5.4!}.
1139 +
1140 +@item Expression results as strings
1141 +You can write @samp{%@var{expr}} to evaluate the expression @var{expr}
1142 +and use the result as a string.  
1143 +@end table
1144 +
1145 +@node GNU Free Documentation License
1146 +@chapter GNU Free Documentation License
1147 +
1148 +                GNU Free Documentation License
1149 +                
1150 +                   Version 1.1, March 2000
1151 +
1152 + Copyright (C) 2000  Free Software Foundation, Inc.
1153 +  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1154 +     
1155 + Everyone is permitted to copy and distribute verbatim copies
1156 + of this license document, but changing it is not allowed.
1157 +
1158 +
1159 +0. PREAMBLE
1160 +
1161 +The purpose of this License is to make a manual, textbook, or other
1162 +written document "free" in the sense of freedom: to assure everyone
1163 +the effective freedom to copy and redistribute it, with or without
1164 +modifying it, either commercially or noncommercially.  Secondarily,
1165 +this License preserves for the author and publisher a way to get
1166 +credit for their work, while not being considered responsible for
1167 +modifications made by others.
1168 +
1169 +This License is a kind of "copyleft", which means that derivative
1170 +works of the document must themselves be free in the same sense.  It
1171 +complements the GNU General Public License, which is a copyleft
1172 +license designed for free software.
1173 +
1174 +We have designed this License in order to use it for manuals for free
1175 +software, because free software needs free documentation: a free
1176 +program should come with manuals providing the same freedoms that the
1177 +software does.  But this License is not limited to software manuals;
1178 +it can be used for any textual work, regardless of subject matter or
1179 +whether it is published as a printed book.  We recommend this License
1180 +principally for works whose purpose is instruction or reference.
1181 +
1182 +
1183 +1. APPLICABILITY AND DEFINITIONS
1184 +
1185 +This License applies to any manual or other work that contains a
1186 +notice placed by the copyright holder saying it can be distributed
1187 +under the terms of this License.  The "Document", below, refers to any
1188 +such manual or work.  Any member of the public is a licensee, and is
1189 +addressed as "you".
1190 +
1191 +A "Modified Version" of the Document means any work containing the
1192 +Document or a portion of it, either copied verbatim, or with
1193 +modifications and/or translated into another language.
1194 +
1195 +A "Secondary Section" is a named appendix or a front-matter section of
1196 +the Document that deals exclusively with the relationship of the
1197 +publishers or authors of the Document to the Document's overall subject
1198 +(or to related matters) and contains nothing that could fall directly
1199 +within that overall subject.  (For example, if the Document is in part a
1200 +textbook of mathematics, a Secondary Section may not explain any
1201 +mathematics.)  The relationship could be a matter of historical
1202 +connection with the subject or with related matters, or of legal,
1203 +commercial, philosophical, ethical or political position regarding
1204 +them.
1205 +
1206 +The "Invariant Sections" are certain Secondary Sections whose titles
1207 +are designated, as being those of Invariant Sections, in the notice
1208 +that says that the Document is released under this License.
1209 +
1210 +The "Cover Texts" are certain short passages of text that are listed,
1211 +as Front-Cover Texts or Back-Cover Texts, in the notice that says that
1212 +the Document is released under this License.
1213 +
1214 +A "Transparent" copy of the Document means a machine-readable copy,
1215 +represented in a format whose specification is available to the
1216 +general public, whose contents can be viewed and edited directly and
1217 +straightforwardly with generic text editors or (for images composed of
1218 +pixels) generic paint programs or (for drawings) some widely available
1219 +drawing editor, and that is suitable for input to text formatters or
1220 +for automatic translation to a variety of formats suitable for input
1221 +to text formatters.  A copy made in an otherwise Transparent file
1222 +format whose markup has been designed to thwart or discourage
1223 +subsequent modification by readers is not Transparent.  A copy that is
1224 +not "Transparent" is called "Opaque".
1225 +
1226 +Examples of suitable formats for Transparent copies include plain
1227 +ASCII without markup, Texinfo input format, LaTeX input format, SGML
1228 +or XML using a publicly available DTD, and standard-conforming simple
1229 +HTML designed for human modification.  Opaque formats include
1230 +PostScript, PDF, proprietary formats that can be read and edited only
1231 +by proprietary word processors, SGML or XML for which the DTD and/or
1232 +processing tools are not generally available, and the
1233 +machine-generated HTML produced by some word processors for output
1234 +purposes only.
1235 +
1236 +The "Title Page" means, for a printed book, the title page itself,
1237 +plus such following pages as are needed to hold, legibly, the material
1238 +this License requires to appear in the title page.  For works in
1239 +formats which do not have any title page as such, "Title Page" means
1240 +the text near the most prominent appearance of the work's title,
1241 +preceding the beginning of the body of the text.
1242 +
1243 +
1244 +2. VERBATIM COPYING
1245 +
1246 +You may copy and distribute the Document in any medium, either
1247 +commercially or noncommercially, provided that this License, the
1248 +copyright notices, and the license notice saying this License applies
1249 +to the Document are reproduced in all copies, and that you add no other
1250 +conditions whatsoever to those of this License.  You may not use
1251 +technical measures to obstruct or control the reading or further
1252 +copying of the copies you make or distribute.  However, you may accept
1253 +compensation in exchange for copies.  If you distribute a large enough
1254 +number of copies you must also follow the conditions in section 3.
1255 +
1256 +You may also lend copies, under the same conditions stated above, and
1257 +you may publicly display copies.
1258 +
1259 +
1260 +3. COPYING IN QUANTITY
1261 +
1262 +If you publish printed copies of the Document numbering more than 100,
1263 +and the Document's license notice requires Cover Texts, you must enclose
1264 +the copies in covers that carry, clearly and legibly, all these Cover
1265 +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
1266 +the back cover.  Both covers must also clearly and legibly identify
1267 +you as the publisher of these copies.  The front cover must present
1268 +the full title with all words of the title equally prominent and
1269 +visible.  You may add other material on the covers in addition.
1270 +Copying with changes limited to the covers, as long as they preserve
1271 +the title of the Document and satisfy these conditions, can be treated
1272 +as verbatim copying in other respects.
1273 +
1274 +If the required texts for either cover are too voluminous to fit
1275 +legibly, you should put the first ones listed (as many as fit
1276 +reasonably) on the actual cover, and continue the rest onto adjacent
1277 +pages.
1278 +
1279 +If you publish or distribute Opaque copies of the Document numbering
1280 +more than 100, you must either include a machine-readable Transparent
1281 +copy along with each Opaque copy, or state in or with each Opaque copy
1282 +a publicly-accessible computer-network location containing a complete
1283 +Transparent copy of the Document, free of added material, which the
1284 +general network-using public has access to download anonymously at no
1285 +charge using public-standard network protocols.  If you use the latter
1286 +option, you must take reasonably prudent steps, when you begin
1287 +distribution of Opaque copies in quantity, to ensure that this
1288 +Transparent copy will remain thus accessible at the stated location
1289 +until at least one year after the last time you distribute an Opaque
1290 +copy (directly or through your agents or retailers) of that edition to
1291 +the public.
1292 +
1293 +It is requested, but not required, that you contact the authors of the
1294 +Document well before redistributing any large number of copies, to give
1295 +them a chance to provide you with an updated version of the Document.
1296 +
1297 +
1298 +4. MODIFICATIONS
1299 +
1300 +You may copy and distribute a Modified Version of the Document under
1301 +the conditions of sections 2 and 3 above, provided that you release
1302 +the Modified Version under precisely this License, with the Modified
1303 +Version filling the role of the Document, thus licensing distribution
1304 +and modification of the Modified Version to whoever possesses a copy
1305 +of it.  In addition, you must do these things in the Modified Version:
1306 +
1307 +A. Use in the Title Page (and on the covers, if any) a title distinct
1308 +   from that of the Document, and from those of previous versions
1309 +   (which should, if there were any, be listed in the History section
1310 +   of the Document).  You may use the same title as a previous version
1311 +   if the original publisher of that version gives permission.
1312 +B. List on the Title Page, as authors, one or more persons or entities
1313 +   responsible for authorship of the modifications in the Modified
1314 +   Version, together with at least five of the principal authors of the
1315 +   Document (all of its principal authors, if it has less than five).
1316 +C. State on the Title page the name of the publisher of the
1317 +   Modified Version, as the publisher.
1318 +D. Preserve all the copyright notices of the Document.
1319 +E. Add an appropriate copyright notice for your modifications
1320 +   adjacent to the other copyright notices.
1321 +F. Include, immediately after the copyright notices, a license notice
1322 +   giving the public permission to use the Modified Version under the
1323 +   terms of this License, in the form shown in the Addendum below.
1324 +G. Preserve in that license notice the full lists of Invariant Sections
1325 +   and required Cover Texts given in the Document's license notice.
1326 +H. Include an unaltered copy of this License.
1327 +I. Preserve the section entitled "History", and its title, and add to
1328 +   it an item stating at least the title, year, new authors, and
1329 +   publisher of the Modified Version as given on the Title Page.  If
1330 +   there is no section entitled "History" in the Document, create one
1331 +   stating the title, year, authors, and publisher of the Document as
1332 +   given on its Title Page, then add an item describing the Modified
1333 +   Version as stated in the previous sentence.
1334 +J. Preserve the network location, if any, given in the Document for
1335 +   public access to a Transparent copy of the Document, and likewise
1336 +   the network locations given in the Document for previous versions
1337 +   it was based on.  These may be placed in the "History" section.
1338 +   You may omit a network location for a work that was published at
1339 +   least four years before the Document itself, or if the original
1340 +   publisher of the version it refers to gives permission.
1341 +K. In any section entitled "Acknowledgements" or "Dedications",
1342 +   preserve the section's title, and preserve in the section all the
1343 +   substance and tone of each of the contributor acknowledgements
1344 +   and/or dedications given therein.
1345 +L. Preserve all the Invariant Sections of the Document,
1346 +   unaltered in their text and in their titles.  Section numbers
1347 +   or the equivalent are not considered part of the section titles.
1348 +M. Delete any section entitled "Endorsements".  Such a section
1349 +   may not be included in the Modified Version.
1350 +N. Do not retitle any existing section as "Endorsements"
1351 +   or to conflict in title with any Invariant Section.
1352 +
1353 +If the Modified Version includes new front-matter sections or
1354 +appendices that qualify as Secondary Sections and contain no material
1355 +copied from the Document, you may at your option designate some or all
1356 +of these sections as invariant.  To do this, add their titles to the
1357 +list of Invariant Sections in the Modified Version's license notice.
1358 +These titles must be distinct from any other section titles.
1359 +
1360 +You may add a section entitled "Endorsements", provided it contains
1361 +nothing but endorsements of your Modified Version by various
1362 +parties--for example, statements of peer review or that the text has
1363 +been approved by an organization as the authoritative definition of a
1364 +standard.
1365 +
1366 +You may add a passage of up to five words as a Front-Cover Text, and a
1367 +passage of up to 25 words as a Back-Cover Text, to the end of the list
1368 +of Cover Texts in the Modified Version.  Only one passage of
1369 +Front-Cover Text and one of Back-Cover Text may be added by (or
1370 +through arrangements made by) any one entity.  If the Document already
1371 +includes a cover text for the same cover, previously added by you or
1372 +by arrangement made by the same entity you are acting on behalf of,
1373 +you may not add another; but you may replace the old one, on explicit
1374 +permission from the previous publisher that added the old one.
1375 +
1376 +The author(s) and publisher(s) of the Document do not by this License
1377 +give permission to use their names for publicity for or to assert or
1378 +imply endorsement of any Modified Version.
1379 +
1380 +
1381 +5. COMBINING DOCUMENTS
1382 +
1383 +You may combine the Document with other documents released under this
1384 +License, under the terms defined in section 4 above for modified
1385 +versions, provided that you include in the combination all of the
1386 +Invariant Sections of all of the original documents, unmodified, and
1387 +list them all as Invariant Sections of your combined work in its
1388 +license notice.
1389 +
1390 +The combined work need only contain one copy of this License, and
1391 +multiple identical Invariant Sections may be replaced with a single
1392 +copy.  If there are multiple Invariant Sections with the same name but
1393 +different contents, make the title of each such section unique by
1394 +adding at the end of it, in parentheses, the name of the original
1395 +author or publisher of that section if known, or else a unique number.
1396 +Make the same adjustment to the section titles in the list of
1397 +Invariant Sections in the license notice of the combined work.
1398 +
1399 +In the combination, you must combine any sections entitled "History"
1400 +in the various original documents, forming one section entitled
1401 +"History"; likewise combine any sections entitled "Acknowledgements",
1402 +and any sections entitled "Dedications".  You must delete all sections
1403 +entitled "Endorsements."
1404 +
1405 +
1406 +6. COLLECTIONS OF DOCUMENTS
1407 +
1408 +You may make a collection consisting of the Document and other documents
1409 +released under this License, and replace the individual copies of this
1410 +License in the various documents with a single copy that is included in
1411 +the collection, provided that you follow the rules of this License for
1412 +verbatim copying of each of the documents in all other respects.
1413 +
1414 +You may extract a single document from such a collection, and distribute
1415 +it individually under this License, provided you insert a copy of this
1416 +License into the extracted document, and follow this License in all
1417 +other respects regarding verbatim copying of that document.
1418 +
1419 +
1420 +7. AGGREGATION WITH INDEPENDENT WORKS
1421 +
1422 +A compilation of the Document or its derivatives with other separate
1423 +and independent documents or works, in or on a volume of a storage or
1424 +distribution medium, does not as a whole count as a Modified Version
1425 +of the Document, provided no compilation copyright is claimed for the
1426 +compilation.  Such a compilation is called an "aggregate", and this
1427 +License does not apply to the other self-contained works thus compiled
1428 +with the Document, on account of their being thus compiled, if they
1429 +are not themselves derivative works of the Document.
1430 +
1431 +If the Cover Text requirement of section 3 is applicable to these
1432 +copies of the Document, then if the Document is less than one quarter
1433 +of the entire aggregate, the Document's Cover Texts may be placed on
1434 +covers that surround only the Document within the aggregate.
1435 +Otherwise they must appear on covers around the whole aggregate.
1436 +
1437 +
1438 +8. TRANSLATION
1439 +
1440 +Translation is considered a kind of modification, so you may
1441 +distribute translations of the Document under the terms of section 4.
1442 +Replacing Invariant Sections with translations requires special
1443 +permission from their copyright holders, but you may include
1444 +translations of some or all Invariant Sections in addition to the
1445 +original versions of these Invariant Sections.  You may include a
1446 +translation of this License provided that you also include the
1447 +original English version of this License.  In case of a disagreement
1448 +between the translation and the original English version of this
1449 +License, the original English version will prevail.
1450 +
1451 +
1452 +9. TERMINATION
1453 +
1454 +You may not copy, modify, sublicense, or distribute the Document except
1455 +as expressly provided for under this License.  Any other attempt to
1456 +copy, modify, sublicense or distribute the Document is void, and will
1457 +automatically terminate your rights under this License.  However,
1458 +parties who have received copies, or rights, from you under this
1459 +License will not have their licenses terminated so long as such
1460 +parties remain in full compliance.
1461 +
1462 +
1463 +10. FUTURE REVISIONS OF THIS LICENSE
1464 +
1465 +The Free Software Foundation may publish new, revised versions
1466 +of the GNU Free Documentation License from time to time.  Such new
1467 +versions will be similar in spirit to the present version, but may
1468 +differ in detail to address new problems or concerns.  See
1469 +http://www.gnu.org/copyleft/.
1470 +
1471 +Each version of the License is given a distinguishing version number.
1472 +If the Document specifies that a particular numbered version of this
1473 +License "or any later version" applies to it, you have the option of
1474 +following the terms and conditions either of that specified version or
1475 +of any later version that has been published (not as a draft) by the
1476 +Free Software Foundation.  If the Document does not specify a version
1477 +number of this License, you may choose any version ever published (not
1478 +as a draft) by the Free Software Foundation.
1479 +
1480 +
1481 +ADDENDUM: How to use this License for your documents
1482 +
1483 +To use this License in a document you have written, include a copy of
1484 +the License in the document and put the following copyright and
1485 +license notices just after the title page:
1486 +
1487 +@smallexample
1488 +    Copyright (c)  YEAR  YOUR NAME.
1489 +    Permission is granted to copy, distribute and/or modify this document
1490 +    under the terms of the GNU Free Documentation License, Version 1.1
1491 +    or any later version published by the Free Software Foundation;
1492 +    with the Invariant Sections being LIST THEIR TITLES, with the
1493 +    Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
1494 +    A copy of the license is included in the section entitled "GNU
1495 +    Free Documentation License".
1496 +@end smallexample
1497 +
1498 +If you have no Invariant Sections, write "with no Invariant Sections"
1499 +instead of saying which ones are invariant.  If you have no
1500 +Front-Cover Texts, write "no Front-Cover Texts" instead of
1501 +"Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
1502 +
1503 +If your document contains nontrivial examples of program code, we
1504 +recommend releasing these examples in parallel under your choice of
1505 +free software license, such as the GNU General Public License,
1506 +to permit their use in free software.
1507 +
1508 +@node Index
1509 +@unnumbered Index
1510 +
1511 +@printindex cp
1512 +
1513 +@contents
1514 +@bye
1515 diff -urNbB binutils-2.16.91.0.2.org/gas/gasp.c binutils-2.16.91.0.2/gas/gasp.c
1516 --- binutils-2.16.91.0.2.org/gas/gasp.c 1970-01-01 00:00:00.000000000 +0000
1517 +++ binutils-2.16.91.0.2/gas/gasp.c     2005-07-21 18:31:04.000000000 +0000
1518 @@ -0,0 +1,3983 @@
1519 +/* gasp.c - Gnu assembler preprocessor main program.
1520 +   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
1521 +   Free Software Foundation, Inc.
1522 +
1523 +   Written by Steve and Judy Chamberlain of Cygnus Support,
1524 +      sac@cygnus.com
1525 +
1526 +   This file is part of GASP, the GNU Assembler Preprocessor.
1527 +
1528 +   GASP is free software; you can redistribute it and/or modify
1529 +   it under the terms of the GNU General Public License as published by
1530 +   the Free Software Foundation; either version 2, or (at your option)
1531 +   any later version.
1532 +
1533 +   GASP is distributed in the hope that it will be useful,
1534 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
1535 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1536 +   GNU General Public License for more details.
1537 +
1538 +   You should have received a copy of the GNU General Public License
1539 +   along with GASP; see the file COPYING.  If not, write to the Free
1540 +   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
1541 +   02111-1307, USA.  */
1542 +
1543 +/*
1544 +This program translates the input macros and stuff into a form
1545 +suitable for gas to consume.
1546 +
1547 +  gasp [-sdhau] [-c char] [-o <outfile>] <infile>*
1548 +
1549 +  -s copy source to output
1550 +  -c <char> comments are started with <char> instead of !
1551 +  -u allow unreasonable stuff
1552 +  -p print line numbers
1553 +  -d print debugging stats
1554 +  -s semi colons start comments
1555 +  -a use alternate syntax
1556 +     Pseudo ops can start with or without a .
1557 +     Labels have to be in first column.
1558 +  -I specify include dir
1559 +    Macro arg parameters subsituted by name, don't need the &.
1560 +     String can start with ' too.
1561 +     Strings can be surrounded by <..>
1562 +     A %<exp> in a string evaluates the expression
1563 +     Literal char in a string with !
1564 +*/
1565 +
1566 +#include "config.h"
1567 +#include "bin-bugs.h"
1568 +
1569 +#include <assert.h>
1570 +#include <stdio.h>
1571 +#include <string.h>
1572 +#include "getopt.h"
1573 +
1574 +#ifdef HAVE_STDLIB_H
1575 +#include <stdlib.h>
1576 +#endif
1577 +
1578 +#ifdef NEED_MALLOC_DECLARATION
1579 +extern char *malloc ();
1580 +#endif
1581 +
1582 +#include "ansidecl.h"
1583 +#include "libiberty.h"
1584 +#include "safe-ctype.h"
1585 +#include "sb.h"
1586 +#include "macro.h"
1587 +#include "asintl.h"
1588 +#include "xregex.h"
1589 +
1590 +char *program_version = "1.2";
1591 +
1592 +/* This is normally declared in as.h, but we don't include that.  We
1593 +   need the function because other files linked with gasp.c might call
1594 +   it.  */
1595 +extern void as_abort PARAMS ((const char *, int, const char *));
1596 +
1597 +/* The default obstack chunk size.  If we set this to zero, the
1598 +   obstack code will use whatever will fit in a 4096 byte block.  This
1599 +   is used by the hash table code used by macro.c.  */
1600 +int chunksize = 0;
1601 +
1602 +#define MAX_INCLUDES 30                /* Maximum include depth.  */
1603 +#define MAX_REASONABLE 1000    /* Maximum number of expansions.  */
1604 +
1605 +int unreasonable;              /* -u on command line.  */
1606 +int stats;                     /* -d on command line.  */
1607 +int print_line_number;         /* -p flag on command line.  */
1608 +int copysource;                        /* -c flag on command line.  */
1609 +int warnings;                  /* Number of WARNINGs generated so far.  */
1610 +int errors;                    /* Number of ERRORs generated so far.  */
1611 +int fatals;                    /* Number of fatal ERRORs generated so far (either 0 or 1).  */
1612 +int alternate = 0;              /* -a on command line.  */
1613 +int mri = 0;                   /* -M on command line.  */
1614 +char comment_char = '!';
1615 +int radix = 10;                        /* Default radix.  */
1616 +
1617 +int had_end; /* Seen .END.  */
1618 +
1619 +/* The output stream.  */
1620 +FILE *outfile;
1621 +
1622 +/* The attributes of each character are stored as a bit pattern
1623 +   chartype, which gives us quick tests.  */
1624 +
1625 +#define FIRSTBIT 1
1626 +#define NEXTBIT  2
1627 +#define SEPBIT   4
1628 +#define WHITEBIT 8
1629 +#define COMMENTBIT 16
1630 +#define BASEBIT  32
1631 +#define ISCOMMENTCHAR(x) (chartype[(unsigned char)(x)] & COMMENTBIT)
1632 +#define ISFIRSTCHAR(x)  (chartype[(unsigned char)(x)] & FIRSTBIT)
1633 +#define ISNEXTCHAR(x)   (chartype[(unsigned char)(x)] & NEXTBIT)
1634 +#define ISSEP(x)        (chartype[(unsigned char)(x)] & SEPBIT)
1635 +#define ISWHITE(x)      (chartype[(unsigned char)(x)] & WHITEBIT)
1636 +#define ISBASE(x)       (chartype[(unsigned char)(x)] & BASEBIT)
1637 +static char chartype[256];
1638 +
1639 +/* Conditional assembly uses the `ifstack'.  Each aif pushes another
1640 +   entry onto the stack, and sets the on flag if it should.  The aelse
1641 +   sets hadelse, and toggles on.  An aend pops a level.  We limit to
1642 +   100 levels of nesting, not because we're facists pigs with read
1643 +   only minds, but because more than 100 levels of nesting is probably
1644 +   a bug in the user's macro structure.  */
1645 +
1646 +#define IFNESTING 100
1647 +struct {
1648 +  int on;                      /* Is the level being output.  */
1649 +  int hadelse;                 /* Has an aelse been seen.  */
1650 +} ifstack[IFNESTING];
1651 +
1652 +int ifi;
1653 +
1654 +/* The final and intermediate results of expression evaluation are kept in
1655 +   exp_t's.  Note that a symbol is not an sb, but a pointer into the input
1656 +   line.  It must be coped somewhere safe before the next line is read in.  */
1657 +
1658 +typedef struct {
1659 +  char *name;
1660 +  int len;
1661 +} symbol;
1662 +
1663 +typedef struct {
1664 +  int value;                   /* Constant part.  */
1665 +  symbol add_symbol;           /* Name part.  */
1666 +  symbol sub_symbol;           /* Name part.  */
1667 +} exp_t;
1668 +
1669 +/* Hashing is done in a pretty standard way.  A hash_table has a
1670 +   pointer to a vector of pointers to hash_entrys, and the size of the
1671 +   vector.  A hash_entry contains a union of all the info we like to
1672 +   store in hash table.  If there is a hash collision, hash_entries
1673 +   with the same hash are kept in a chain.  */
1674 +
1675 +/* What the data in a hash_entry means.  */
1676 +typedef enum {
1677 +  hash_integer,                        /* Name->integer mapping.  */
1678 +  hash_string,                 /* Name->string mapping.  */
1679 +  hash_macro,                  /* Name is a macro.  */
1680 +  hash_formal                  /* Name is a formal argument.  */
1681 +} hash_type;
1682 +
1683 +typedef struct hs {
1684 +  sb key;                      /* Symbol name.  */
1685 +  hash_type type;              /* Symbol meaning.  */
1686 +  union {
1687 +    sb s;
1688 +    int i;
1689 +    struct macro_struct *m;
1690 +    struct formal_struct *f;
1691 +  } value;
1692 +  struct hs *next;             /* Next hash_entry with same hash key.  */
1693 +} hash_entry;
1694 +
1695 +typedef struct {
1696 +  hash_entry **table;
1697 +  int size;
1698 +} hash_table;
1699 +
1700 +/* How we nest files and expand macros etc.
1701 +
1702 +   We keep a stack of of include_stack structs.  Each include file
1703 +   pushes a new level onto the stack.  We keep an sb with a pushback
1704 +   too.  unget chars are pushed onto the pushback sb, getchars first
1705 +   checks the pushback sb before reading from the input stream.
1706 +
1707 +   Small things are expanded by adding the text of the item onto the
1708 +   pushback sb.  Larger items are grown by pushing a new level and
1709 +   allocating the entire pushback buf for the item.  Each time
1710 +   something like a macro is expanded, the stack index is changed.  We
1711 +   can then perform an exitm by popping all entries off the stack with
1712 +   the same stack index.  If we're being reasonable, we can detect
1713 +   recusive expansion by checking the index is reasonably small.  */
1714 +
1715 +typedef enum {
1716 +  include_file, include_repeat, include_while, include_macro
1717 +} include_type;
1718 +
1719 +struct include_stack {
1720 +  sb pushback;                 /* Current pushback stream.  */
1721 +  int pushback_index;          /* Next char to read from stream.  */
1722 +  FILE *handle;                        /* Open file.  */
1723 +  sb name;                     /* Name of file.  */
1724 +  int linecount;               /* Number of lines read so far.  */
1725 +  include_type type;
1726 +  int index;                   /* Index of this layer.  */
1727 +} include_stack[MAX_INCLUDES];
1728 +
1729 +struct include_stack *sp;
1730 +#define isp (sp - include_stack)
1731 +
1732 +/* Include file list.  */
1733 +
1734 +typedef struct include_path {
1735 +  struct include_path *next;
1736 +  sb path;
1737 +} include_path;
1738 +
1739 +include_path *paths_head;
1740 +include_path *paths_tail;
1741 +
1742 +static void quit PARAMS ((void));
1743 +static void hash_new_table PARAMS ((int, hash_table *));
1744 +static int hash PARAMS ((sb *));
1745 +static hash_entry *hash_create PARAMS ((hash_table *, sb *));
1746 +static void hash_add_to_string_table PARAMS ((hash_table *, sb *, sb *, int));
1747 +static void hash_add_to_int_table PARAMS ((hash_table *, sb *, int));
1748 +static hash_entry *hash_lookup PARAMS ((hash_table *, sb *));
1749 +static void checkconst PARAMS ((int, exp_t *));
1750 +static int is_flonum PARAMS ((int, sb *));
1751 +static int chew_flonum PARAMS ((int, sb *, sb *));
1752 +static int sb_strtol PARAMS ((int, sb *, int, int *));
1753 +static int level_0 PARAMS ((int, sb *, exp_t *));
1754 +static int level_1 PARAMS ((int, sb *, exp_t *));
1755 +static int level_2 PARAMS ((int, sb *, exp_t *));
1756 +static int level_3 PARAMS ((int, sb *, exp_t *));
1757 +static int level_4 PARAMS ((int, sb *, exp_t *));
1758 +static int level_5 PARAMS ((int, sb *, exp_t *));
1759 +static int exp_parse PARAMS ((int, sb *, exp_t *));
1760 +static void exp_string PARAMS ((exp_t *, sb *));
1761 +static int exp_get_abs PARAMS ((const char *, int, sb *, int *));
1762 +#if 0
1763 +static void strip_comments PARAMS ((sb *));
1764 +#endif
1765 +static void unget PARAMS ((int));
1766 +static void include_buf PARAMS ((sb *, sb *, include_type, int));
1767 +static void include_print_where_line PARAMS ((FILE *));
1768 +static void include_print_line PARAMS ((FILE *));
1769 +static int get_line PARAMS ((sb *));
1770 +static int grab_label PARAMS ((sb *, sb *));
1771 +static void change_base PARAMS ((int, sb *, sb *));
1772 +static void do_end PARAMS ((sb *));
1773 +static void do_assign PARAMS ((int, int, sb *));
1774 +static void do_radix PARAMS ((sb *));
1775 +static int get_opsize PARAMS ((int, sb *, int *));
1776 +static int eol PARAMS ((int, sb *));
1777 +static void do_data PARAMS ((int, sb *, int));
1778 +static void do_datab PARAMS ((int, sb *));
1779 +static void do_align PARAMS ((int, sb *));
1780 +static void do_res PARAMS ((int, sb *, int));
1781 +static void do_export PARAMS ((sb *));
1782 +static void do_print PARAMS ((int, sb *));
1783 +static void do_heading PARAMS ((int, sb *));
1784 +static void do_page PARAMS ((void));
1785 +static void do_form PARAMS ((int, sb *));
1786 +static int get_any_string PARAMS ((int, sb *, sb *, int, int));
1787 +static int skip_openp PARAMS ((int, sb *));
1788 +static int skip_closep PARAMS ((int, sb *));
1789 +static int dolen PARAMS ((int, sb *, sb *));
1790 +static int doinstr PARAMS ((int, sb *, sb *));
1791 +static int dosubstr PARAMS ((int, sb *, sb *));
1792 +static void process_assigns PARAMS ((int, sb *, sb *));
1793 +static int get_and_process PARAMS ((int, sb *, sb *));
1794 +static void process_file PARAMS ((void));
1795 +static void free_old_entry PARAMS ((hash_entry *));
1796 +static void do_assigna PARAMS ((int, sb *));
1797 +static void do_assignc PARAMS ((int, sb *));
1798 +static void do_reg PARAMS ((int, sb *));
1799 +static int condass_lookup_name PARAMS ((sb *, int, sb *, int));
1800 +static int whatcond PARAMS ((int, sb *, int *));
1801 +static int istrue PARAMS ((int, sb *));
1802 +static void do_aif PARAMS ((int, sb *));
1803 +static void do_aelse PARAMS ((void));
1804 +static void do_aendi PARAMS ((void));
1805 +static int condass_on PARAMS ((void));
1806 +static void do_if PARAMS ((int, sb *, int));
1807 +static int get_mri_string PARAMS ((int, sb *, sb *, int));
1808 +static void do_ifc PARAMS ((int, sb *, int));
1809 +static void do_aendr PARAMS ((void));
1810 +static void do_awhile PARAMS ((int, sb *));
1811 +static void do_aendw PARAMS ((void));
1812 +static void do_exitm PARAMS ((void));
1813 +static void do_arepeat PARAMS ((int, sb *));
1814 +static void do_endm PARAMS ((void));
1815 +static void do_irp PARAMS ((int, sb *, int));
1816 +static void do_local PARAMS ((int, sb *));
1817 +static void do_macro PARAMS ((int, sb *));
1818 +static int macro_op PARAMS ((int, sb *));
1819 +static int getstring PARAMS ((int, sb *, sb *));
1820 +static void do_sdata PARAMS ((int, sb *, int));
1821 +static void do_sdatab PARAMS ((int, sb *));
1822 +static int new_file PARAMS ((const char *));
1823 +static void do_include PARAMS ((int, sb *));
1824 +static void include_pop PARAMS ((void));
1825 +static int get PARAMS ((void));
1826 +static int linecount PARAMS ((void));
1827 +static int include_next_index PARAMS ((void));
1828 +static void chartype_init PARAMS ((void));
1829 +static int process_pseudo_op PARAMS ((int, sb *, sb *));
1830 +static void add_keyword PARAMS ((const char *, int));
1831 +static void process_init PARAMS ((void));
1832 +static void do_define PARAMS ((const char *));
1833 +static void show_usage PARAMS ((FILE *, int));
1834 +static void show_help PARAMS ((void));
1835 +
1836 +/* --- functions recently removed from sb.c --- */
1837 +
1838 +/* put a null at the end of the sb at in and return the start of the
1839 + *    string, so that it can be used as an arg to printf %s.  */
1840 +
1841 +static char *
1842 +sb_name (sb *in)
1843 +{
1844 +  /* stick a null on the end of the string */
1845 +  sb_add_char (in, 0);
1846 +  return in->ptr;
1847 +}
1848 +
1849 +/* print the sb at ptr to the output file */
1850 +
1851 +static void
1852 +sb_print (FILE *outfile, sb *ptr)
1853 +{
1854 +  int i;
1855 +  int nc = 0;
1856 +
1857 +  for (i = 0; i < ptr->len; i++)
1858 +    {
1859 +      if (nc)
1860 +       {
1861 +         fprintf (outfile, ",");
1862 +       }
1863 +      fprintf (outfile, "%d", ptr->ptr[i]);
1864 +      nc = 1;
1865 +    }
1866 +}
1867 +
1868 +/* print the sb at ptr to the output file */
1869 +
1870 +static void
1871 +sb_print_at (FILE *outfile, int idx, sb *ptr)
1872 +{
1873 +  int i;
1874 +  for (i = idx; i < ptr->len; i++)
1875 +    putc (ptr->ptr[i], outfile);
1876 +}
1877 +
1878 +#define FATAL(x)                               \
1879 +  do                                           \
1880 +    {                                          \
1881 +      include_print_where_line (stderr);       \
1882 +      fprintf x;                               \
1883 +      fatals++;                                        \
1884 +      quit ();                                 \
1885 +    }                                          \
1886 +  while (0)
1887 +
1888 +#define ERROR(x)                               \
1889 +  do                                           \
1890 +    {                                          \
1891 +      include_print_where_line (stderr);       \
1892 +      fprintf x;                               \
1893 +      errors++;                                        \
1894 +    }                                          \
1895 +  while (0)
1896 +
1897 +#define WARNING(x)                             \
1898 +  do                                           \
1899 +    {                                          \
1900 +      include_print_where_line (stderr);       \
1901 +      fprintf x;                               \
1902 +      warnings++;                              \
1903 +    }                                          \
1904 +  while (0)
1905 +
1906 +/* Exit the program and return the right ERROR code.  */
1907 +
1908 +static void
1909 +quit ()
1910 +{
1911 +  int exitcode;
1912 +  if (fatals + errors)
1913 +    exitcode = 1;
1914 +  else
1915 +    exitcode = 0;
1916 +
1917 +  exit (exitcode);
1918 +}
1919 +
1920 +/* Hash table maintenance.  */
1921 +
1922 +/* Build a new hash table with size buckets
1923 +   and fill in the info at ptr.  */
1924 +
1925 +static void
1926 +hash_new_table (size, ptr)
1927 +     int size;
1928 +     hash_table *ptr;
1929 +{
1930 +  int i;
1931 +  ptr->size = size;
1932 +  ptr->table = (hash_entry **) xmalloc (size * (sizeof (hash_entry *)));
1933 +  /* Fill with null-pointer, not zero-bit-pattern.  */
1934 +  for (i = 0; i < size; i++)
1935 +    ptr->table[i] = 0;
1936 +}
1937 +
1938 +/* Calculate and return the hash value of the sb at key.  */
1939 +
1940 +static int
1941 +hash (key)
1942 +     sb *key;
1943 +{
1944 +  int k = 0x1234;
1945 +  int i;
1946 +  char *p = key->ptr;
1947 +  for (i = 0; i < key->len; i++)
1948 +    {
1949 +      k ^= (k << 2) ^ *p;
1950 +      p++;
1951 +    }
1952 +  return k & 0xf0fff;
1953 +}
1954 +
1955 +/* Look up key in hash_table tab.  If present, then return it,
1956 +   otherwise build a new one and fill it with hash_integer.  */
1957 +
1958 +static hash_entry *
1959 +hash_create (tab, key)
1960 +     hash_table *tab;
1961 +     sb *key;
1962 +{
1963 +  int k = hash (key) % tab->size;
1964 +  hash_entry *p;
1965 +  hash_entry **table = tab->table;
1966 +
1967 +  p = table[k];
1968 +
1969 +  while (1)
1970 +    {
1971 +      if (!p)
1972 +       {
1973 +         hash_entry *n = (hash_entry *) xmalloc (sizeof (hash_entry));
1974 +         n->next = table[k];
1975 +         sb_new (&n->key);
1976 +         sb_add_sb (&n->key, key);
1977 +         table[k] = n;
1978 +         n->type = hash_integer;
1979 +         return n;
1980 +       }
1981 +      if (strncmp (table[k]->key.ptr, key->ptr, key->len) == 0)
1982 +       {
1983 +         return p;
1984 +       }
1985 +      p = p->next;
1986 +    }
1987 +}
1988 +
1989 +/* Add sb name with key into hash_table tab.
1990 +   If replacing old value and again, then ERROR.  */
1991 +
1992 +static void
1993 +hash_add_to_string_table (tab, key, name, again)
1994 +     hash_table *tab;
1995 +     sb *key;
1996 +     sb *name;
1997 +     int again;
1998 +{
1999 +  hash_entry *ptr = hash_create (tab, key);
2000 +  if (ptr->type == hash_integer)
2001 +    {
2002 +      sb_new (&ptr->value.s);
2003 +    }
2004 +  if (ptr->value.s.len)
2005 +    {
2006 +      if (!again)
2007 +       ERROR ((stderr, _("redefinition not allowed\n")));
2008 +    }
2009 +
2010 +  ptr->type = hash_string;
2011 +  sb_reset (&ptr->value.s);
2012 +
2013 +  sb_add_sb (&ptr->value.s, name);
2014 +}
2015 +
2016 +/* Add integer name to hash_table tab with sb key.  */
2017 +
2018 +static void
2019 +hash_add_to_int_table (tab, key, name)
2020 +     hash_table *tab;
2021 +     sb *key;
2022 +     int name;
2023 +{
2024 +  hash_entry *ptr = hash_create (tab, key);
2025 +  ptr->value.i = name;
2026 +}
2027 +
2028 +/* Look up sb key in hash_table tab.
2029 +   If found, return hash_entry result, else 0.  */
2030 +
2031 +static hash_entry *
2032 +hash_lookup (tab, key)
2033 +     hash_table *tab;
2034 +     sb *key;
2035 +{
2036 +  int k = hash (key) % tab->size;
2037 +  hash_entry **table = tab->table;
2038 +  hash_entry *p = table[k];
2039 +  while (p)
2040 +    {
2041 +      if (p->key.len == key->len
2042 +         && strncmp (p->key.ptr, key->ptr, key->len) == 0)
2043 +       return p;
2044 +      p = p->next;
2045 +    }
2046 +  return 0;
2047 +}
2048 +
2049 +/* expressions
2050 +
2051 +   are handled in a really simple recursive decent way. each bit of
2052 +   the machine takes an index into an sb and a pointer to an exp_t,
2053 +   modifies the *exp_t and returns the index of the first character
2054 +   past the part of the expression parsed.
2055 +
2056 + expression precedence:
2057 +  ( )
2058 + unary + - ~
2059 +  * /
2060 +  + -
2061 +  &
2062 +  | ~
2063 +*/
2064 +
2065 +/* Make sure that the exp_t at term is constant.
2066 +   If not the give the op ERROR.  */
2067 +
2068 +static void
2069 +checkconst (op, term)
2070 +     int op;
2071 +     exp_t *term;
2072 +{
2073 +  if (term->add_symbol.len
2074 +      || term->sub_symbol.len)
2075 +    {
2076 +      ERROR ((stderr, _("the %c operator cannot take non-absolute arguments.\n"), op));
2077 +    }
2078 +}
2079 +
2080 +/* Chew the flonum from the string starting at idx.  Adjust idx to
2081 +   point to the next character after the flonum.  */
2082 +
2083 +static int
2084 +chew_flonum (idx, string, out)
2085 +     int idx;
2086 +     sb *string;
2087 +     sb *out;
2088 +{
2089 +  sb buf;
2090 +  regex_t reg;
2091 +  regmatch_t match;
2092 +
2093 +  /* Duplicate and null terminate `string'.  */
2094 +  sb_new (&buf);
2095 +  sb_add_sb (&buf, string);
2096 +  sb_add_char (&buf, '\0');
2097 +
2098 +  if (regcomp (&reg, "([0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?)", REG_EXTENDED) != 0)
2099 +    return idx;
2100 +  if (regexec (&reg, &buf.ptr[idx], 1, &match, 0) != 0)
2101 +    return idx;
2102 +
2103 +  /* Copy the match to the output.  */
2104 +  assert (match.rm_eo >= match.rm_so);
2105 +  sb_add_buffer (out, &buf.ptr[idx], match.rm_eo - match.rm_so);
2106 +
2107 +  sb_kill (&buf);
2108 +  regfree (&reg);
2109 +  idx += match.rm_eo;
2110 +  return idx;
2111 +}
2112 +
2113 +static int
2114 +is_flonum (idx, string)
2115 +     int idx;
2116 +     sb *string;
2117 +{
2118 +  sb buf;
2119 +  regex_t reg;
2120 +  int rc;
2121 +
2122 +  /* Duplicate and null terminate `string'.  */
2123 +  sb_new (&buf);
2124 +  sb_add_sb (&buf, string);
2125 +  sb_add_char (&buf, '\0');
2126 +
2127 +  if (regcomp (&reg, "^[0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?", REG_EXTENDED) != 0)
2128 +    return 0;
2129 +
2130 +  rc = regexec (&reg, &buf.ptr[idx], 0, NULL, 0);
2131 +  sb_kill (&buf);
2132 +  regfree (&reg);
2133 +  return (rc == 0);
2134 +}
2135 +
2136 +/* Turn the number in string at idx into a number of base, fill in
2137 +   ptr, and return the index of the first character not in the number.  */
2138 +
2139 +static int
2140 +sb_strtol (idx, string, base, ptr)
2141 +     int idx;
2142 +     sb *string;
2143 +     int base;
2144 +     int *ptr;
2145 +{
2146 +  int value = 0;
2147 +  idx = sb_skip_white (idx, string);
2148 +
2149 +  while (idx < string->len)
2150 +    {
2151 +      int ch = string->ptr[idx];
2152 +      int dig = 0;
2153 +      if (ISDIGIT (ch))
2154 +       dig = ch - '0';
2155 +      else if (ch >= 'a' && ch <= 'f')
2156 +       dig = ch - 'a' + 10;
2157 +      else if (ch >= 'A' && ch <= 'F')
2158 +       dig = ch - 'A' + 10;
2159 +      else
2160 +       break;
2161 +
2162 +      if (dig >= base)
2163 +       break;
2164 +
2165 +      value = value * base + dig;
2166 +      idx++;
2167 +    }
2168 +  *ptr = value;
2169 +  return idx;
2170 +}
2171 +
2172 +static int
2173 +level_0 (idx, string, lhs)
2174 +     int idx;
2175 +     sb *string;
2176 +     exp_t *lhs;
2177 +{
2178 +  lhs->add_symbol.len = 0;
2179 +  lhs->add_symbol.name = 0;
2180 +
2181 +  lhs->sub_symbol.len = 0;
2182 +  lhs->sub_symbol.name = 0;
2183 +
2184 +  idx = sb_skip_white (idx, string);
2185 +
2186 +  lhs->value = 0;
2187 +
2188 +  if (ISDIGIT (string->ptr[idx]))
2189 +    {
2190 +      idx = sb_strtol (idx, string, 10, &lhs->value);
2191 +    }
2192 +  else if (ISFIRSTCHAR (string->ptr[idx]))
2193 +    {
2194 +      int len = 0;
2195 +      lhs->add_symbol.name = string->ptr + idx;
2196 +      while (idx < string->len && ISNEXTCHAR (string->ptr[idx]))
2197 +       {
2198 +         idx++;
2199 +         len++;
2200 +       }
2201 +      lhs->add_symbol.len = len;
2202 +    }
2203 +  else if (string->ptr[idx] == '"')
2204 +    {
2205 +      sb acc;
2206 +      sb_new (&acc);
2207 +      ERROR ((stderr, _("string where expression expected.\n")));
2208 +      idx = getstring (idx, string, &acc);
2209 +      sb_kill (&acc);
2210 +    }
2211 +  else
2212 +    {
2213 +      ERROR ((stderr, _("can't find primary in expression.\n")));
2214 +      idx++;
2215 +    }
2216 +  return sb_skip_white (idx, string);
2217 +}
2218 +
2219 +static int
2220 +level_1 (idx, string, lhs)
2221 +     int idx;
2222 +     sb *string;
2223 +     exp_t *lhs;
2224 +{
2225 +  idx = sb_skip_white (idx, string);
2226 +
2227 +  switch (string->ptr[idx])
2228 +    {
2229 +    case '+':
2230 +      idx = level_1 (idx + 1, string, lhs);
2231 +      break;
2232 +    case '~':
2233 +      idx = level_1 (idx + 1, string, lhs);
2234 +      checkconst ('~', lhs);
2235 +      lhs->value = ~lhs->value;
2236 +      break;
2237 +    case '-':
2238 +      {
2239 +       symbol t;
2240 +       idx = level_1 (idx + 1, string, lhs);
2241 +       lhs->value = -lhs->value;
2242 +       t = lhs->add_symbol;
2243 +       lhs->add_symbol = lhs->sub_symbol;
2244 +       lhs->sub_symbol = t;
2245 +       break;
2246 +      }
2247 +    case '(':
2248 +      idx++;
2249 +      idx = level_5 (sb_skip_white (idx, string), string, lhs);
2250 +      if (string->ptr[idx] != ')')
2251 +       ERROR ((stderr, _("misplaced closing parens.\n")));
2252 +      else
2253 +       idx++;
2254 +      break;
2255 +    default:
2256 +      idx = level_0 (idx, string, lhs);
2257 +      break;
2258 +    }
2259 +  return sb_skip_white (idx, string);
2260 +}
2261 +
2262 +static int
2263 +level_2 (idx, string, lhs)
2264 +     int idx;
2265 +     sb *string;
2266 +     exp_t *lhs;
2267 +{
2268 +  exp_t rhs;
2269 +
2270 +  idx = level_1 (idx, string, lhs);
2271 +
2272 +  while (idx < string->len && (string->ptr[idx] == '*'
2273 +                              || string->ptr[idx] == '/'))
2274 +    {
2275 +      char op = string->ptr[idx++];
2276 +      idx = level_1 (idx, string, &rhs);
2277 +      switch (op)
2278 +       {
2279 +       case '*':
2280 +         checkconst ('*', lhs);
2281 +         checkconst ('*', &rhs);
2282 +         lhs->value *= rhs.value;
2283 +         break;
2284 +       case '/':
2285 +         checkconst ('/', lhs);
2286 +         checkconst ('/', &rhs);
2287 +         if (rhs.value == 0)
2288 +           ERROR ((stderr, _("attempt to divide by zero.\n")));
2289 +         else
2290 +           lhs->value /= rhs.value;
2291 +         break;
2292 +       }
2293 +    }
2294 +  return sb_skip_white (idx, string);
2295 +}
2296 +
2297 +static int
2298 +level_3 (idx, string, lhs)
2299 +     int idx;
2300 +     sb *string;
2301 +     exp_t *lhs;
2302 +{
2303 +  exp_t rhs;
2304 +
2305 +  idx = level_2 (idx, string, lhs);
2306 +
2307 +  while (idx < string->len
2308 +        && (string->ptr[idx] == '+'
2309 +            || string->ptr[idx] == '-'))
2310 +    {
2311 +      char op = string->ptr[idx++];
2312 +      idx = level_2 (idx, string, &rhs);
2313 +      switch (op)
2314 +       {
2315 +       case '+':
2316 +         lhs->value += rhs.value;
2317 +         if (lhs->add_symbol.name && rhs.add_symbol.name)
2318 +           {
2319 +             ERROR ((stderr, _("can't add two relocatable expressions\n")));
2320 +           }
2321 +         /* Change nn+symbol to symbol + nn.  */
2322 +         if (rhs.add_symbol.name)
2323 +           {
2324 +             lhs->add_symbol = rhs.add_symbol;
2325 +           }
2326 +         break;
2327 +       case '-':
2328 +         lhs->value -= rhs.value;
2329 +         lhs->sub_symbol = rhs.add_symbol;
2330 +         break;
2331 +       }
2332 +    }
2333 +  return sb_skip_white (idx, string);
2334 +}
2335 +
2336 +static int
2337 +level_4 (idx, string, lhs)
2338 +     int idx;
2339 +     sb *string;
2340 +     exp_t *lhs;
2341 +{
2342 +  exp_t rhs;
2343 +
2344 +  idx = level_3 (idx, string, lhs);
2345 +
2346 +  while (idx < string->len &&
2347 +        string->ptr[idx] == '&')
2348 +    {
2349 +      char op = string->ptr[idx++];
2350 +      idx = level_3 (idx, string, &rhs);
2351 +      switch (op)
2352 +       {
2353 +       case '&':
2354 +         checkconst ('&', lhs);
2355 +         checkconst ('&', &rhs);
2356 +         lhs->value &= rhs.value;
2357 +         break;
2358 +       }
2359 +    }
2360 +  return sb_skip_white (idx, string);
2361 +}
2362 +
2363 +static int
2364 +level_5 (idx, string, lhs)
2365 +     int idx;
2366 +     sb *string;
2367 +     exp_t *lhs;
2368 +{
2369 +  exp_t rhs;
2370 +
2371 +  idx = level_4 (idx, string, lhs);
2372 +
2373 +  while (idx < string->len
2374 +        && (string->ptr[idx] == '|' || string->ptr[idx] == '~'))
2375 +    {
2376 +      char op = string->ptr[idx++];
2377 +      idx = level_4 (idx, string, &rhs);
2378 +      switch (op)
2379 +       {
2380 +       case '|':
2381 +         checkconst ('|', lhs);
2382 +         checkconst ('|', &rhs);
2383 +         lhs->value |= rhs.value;
2384 +         break;
2385 +       case '~':
2386 +         checkconst ('~', lhs);
2387 +         checkconst ('~', &rhs);
2388 +         lhs->value ^= rhs.value;
2389 +         break;
2390 +       }
2391 +    }
2392 +  return sb_skip_white (idx, string);
2393 +}
2394 +
2395 +/* Parse the expression at offset idx into string, fill up res with
2396 +   the result.  Return the index of the first char past the
2397 +   expression.  */
2398 +
2399 +static int
2400 +exp_parse (idx, string, res)
2401 +     int idx;
2402 +     sb *string;
2403 +     exp_t *res;
2404 +{
2405 +  return level_5 (sb_skip_white (idx, string), string, res);
2406 +}
2407 +
2408 +/* Turn the expression at exp into text and glue it onto the end of
2409 +   string.  */
2410 +
2411 +static void
2412 +exp_string (exp, string)
2413 +     exp_t *exp;
2414 +     sb *string;
2415 +{
2416 +  int np = 0;
2417 +  int ad = 0;
2418 +  sb_reset (string);
2419 +
2420 +  if (exp->add_symbol.len)
2421 +    {
2422 +      sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
2423 +      np = 1;
2424 +      ad = 1;
2425 +    }
2426 +  if (exp->value)
2427 +    {
2428 +      char buf[20];
2429 +      if (np)
2430 +       sb_add_char (string, '+');
2431 +      sprintf (buf, "%d", exp->value);
2432 +      sb_add_string (string, buf);
2433 +      np = 1;
2434 +      ad = 1;
2435 +    }
2436 +  if (exp->sub_symbol.len)
2437 +    {
2438 +      sb_add_char (string, '-');
2439 +      sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
2440 +      np = 0;
2441 +      ad = 1;
2442 +    }
2443 +
2444 +  if (!ad)
2445 +    sb_add_char (string, '0');
2446 +}
2447 +
2448 +/* Parse the expression at offset idx into sb in.  Return the value in
2449 +   val.  If the expression is not constant, give ERROR emsg.  Return
2450 +   the index of the first character past the end of the expression.  */
2451 +
2452 +static int
2453 +exp_get_abs (emsg, idx, in, val)
2454 +     const char *emsg;
2455 +     int idx;
2456 +     sb *in;
2457 +     int *val;
2458 +{
2459 +  exp_t res;
2460 +  idx = exp_parse (idx, in, &res);
2461 +  if (res.add_symbol.len || res.sub_symbol.len)
2462 +    ERROR ((stderr, "%s", emsg));
2463 +  *val = res.value;
2464 +  return idx;
2465 +}
2466 +
2467 +/* Current label parsed from line.  */
2468 +sb label;
2469 +
2470 +/* Hash table for all assigned variables.  */
2471 +hash_table assign_hash_table;
2472 +
2473 +/* Hash table for keyword.  */
2474 +hash_table keyword_hash_table;
2475 +
2476 +/* Hash table for eq variables.  */
2477 +hash_table vars;
2478 +
2479 +#define in_comment ';'
2480 +
2481 +#if 0
2482 +static void
2483 +strip_comments (out)
2484 +     sb *out;
2485 +{
2486 +  char *s = out->ptr;
2487 +  int i = 0;
2488 +  for (i = 0; i < out->len; i++)
2489 +    {
2490 +      if (ISCOMMENTCHAR (s[i]))
2491 +       {
2492 +         out->len = i;
2493 +         return;
2494 +       }
2495 +    }
2496 +}
2497 +#endif
2498 +
2499 +/* Push back character ch so that it can be read again.  */
2500 +
2501 +static void
2502 +unget (ch)
2503 +     int ch;
2504 +{
2505 +  if (ch == '\n')
2506 +    {
2507 +      sp->linecount--;
2508 +    }
2509 +  if (sp->pushback_index)
2510 +    sp->pushback_index--;
2511 +  else
2512 +    sb_add_char (&sp->pushback, ch);
2513 +}
2514 +
2515 +/* Push the sb ptr onto the include stack, with the given name, type
2516 +   and index.  */
2517 +
2518 +static void
2519 +include_buf (name, ptr, type, index)
2520 +     sb *name;
2521 +     sb *ptr;
2522 +     include_type type;
2523 +     int index;
2524 +{
2525 +  sp++;
2526 +  if (sp - include_stack >= MAX_INCLUDES)
2527 +    FATAL ((stderr, _("unreasonable nesting.\n")));
2528 +  sb_new (&sp->name);
2529 +  sb_add_sb (&sp->name, name);
2530 +  sp->handle = 0;
2531 +  sp->linecount = 1;
2532 +  sp->pushback_index = 0;
2533 +  sp->type = type;
2534 +  sp->index = index;
2535 +  sb_new (&sp->pushback);
2536 +  sb_add_sb (&sp->pushback, ptr);
2537 +}
2538 +
2539 +/* Used in ERROR messages, print info on where the include stack is
2540 +   onto file.  */
2541 +
2542 +static void
2543 +include_print_where_line (file)
2544 +     FILE *file;
2545 +{
2546 +  struct include_stack *p = include_stack + 1;
2547 +
2548 +  while (p <= sp)
2549 +    {
2550 +      fprintf (file, "%s:%d ", sb_name (&p->name), p->linecount - 1);
2551 +      p++;
2552 +    }
2553 +}
2554 +
2555 +/* Used in listings, print the line number onto file.  */
2556 +
2557 +static void
2558 +include_print_line (file)
2559 +     FILE *file;
2560 +{
2561 +  int n;
2562 +  struct include_stack *p = include_stack + 1;
2563 +
2564 +  n = fprintf (file, "%4d", p->linecount);
2565 +  p++;
2566 +  while (p <= sp)
2567 +    {
2568 +      n += fprintf (file, ".%d", p->linecount);
2569 +      p++;
2570 +    }
2571 +  while (n < 8 * 3)
2572 +    {
2573 +      fprintf (file, " ");
2574 +      n++;
2575 +    }
2576 +}
2577 +
2578 +/* Read a line from the top of the include stack into sb in.  */
2579 +
2580 +static int
2581 +get_line (in)
2582 +     sb *in;
2583 +{
2584 +  int online = 0;
2585 +  int more = 1, ch = 0;
2586 +
2587 +  if (copysource)
2588 +    {
2589 +      putc (comment_char, outfile);
2590 +      if (print_line_number)
2591 +       include_print_line (outfile);
2592 +    }
2593 +
2594 +  while (1)
2595 +    {
2596 +      ch = get ();
2597 +
2598 +      while (ch == '\r')
2599 +       ch = get ();
2600 +
2601 +      if (ch == EOF)
2602 +       {
2603 +         if (online)
2604 +           {
2605 +             WARNING ((stderr, _("End of file not at start of line.\n")));
2606 +             if (copysource)
2607 +               putc ('\n', outfile);
2608 +             ch = '\n';
2609 +           }
2610 +         else
2611 +           more = 0;
2612 +         break;
2613 +       }
2614 +
2615 +      if (copysource)
2616 +       {
2617 +         putc (ch, outfile);
2618 +       }
2619 +
2620 +      if (ch == '\n')
2621 +       {
2622 +         ch = get ();
2623 +         online = 0;
2624 +         if (ch == '+')
2625 +           {
2626 +             /* Continued line.  */
2627 +             if (copysource)
2628 +               {
2629 +                 putc (comment_char, outfile);
2630 +                 putc ('+', outfile);
2631 +               }
2632 +             ch = get ();
2633 +           }
2634 +         else
2635 +           {
2636 +             if (ch != EOF)
2637 +               unget (ch);
2638 +             ch = '\n'; break;
2639 +           }
2640 +       }
2641 +      else
2642 +       {
2643 +         sb_add_char (in, ch);
2644 +       }
2645 +      online++;
2646 +    }
2647 +
2648 +  return more ? ch : 0;
2649 +}
2650 +
2651 +/* Find a label from sb in and put it in out.  */
2652 +
2653 +static int
2654 +grab_label (in, out)
2655 +     sb *in;
2656 +     sb *out;
2657 +{
2658 +  int i = 0;
2659 +  sb_reset (out);
2660 +  if (ISFIRSTCHAR (in->ptr[i]) || in->ptr[i] == '\\')
2661 +    {
2662 +      sb_add_char (out, in->ptr[i]);
2663 +      i++;
2664 +      while ((ISNEXTCHAR (in->ptr[i])
2665 +             || in->ptr[i] == '\\'
2666 +             || in->ptr[i] == '&')
2667 +            && i < in->len)
2668 +       {
2669 +         sb_add_char (out, in->ptr[i]);
2670 +         i++;
2671 +       }
2672 +    }
2673 +  return i;
2674 +}
2675 +
2676 +/* Find all strange base stuff and turn into decimal.  Also
2677 +   find all the other numbers and convert them from the default radix.  */
2678 +
2679 +static void
2680 +change_base (idx, in, out)
2681 +     int idx;
2682 +     sb *in;
2683 +     sb *out;
2684 +{
2685 +  char buffer[20];
2686 +
2687 +  while (idx < in->len)
2688 +    {
2689 +      if (in->ptr[idx] == '\\'
2690 +         && idx + 1 < in->len
2691 +         && in->ptr[idx + 1] == '(')
2692 +       {
2693 +         idx += 2;
2694 +         while (idx < in->len
2695 +                && in->ptr[idx] != ')')
2696 +           {
2697 +             sb_add_char (out, in->ptr[idx]);
2698 +             idx++;
2699 +           }
2700 +         if (idx < in->len)
2701 +           idx++;
2702 +       }
2703 +      else if (idx < in->len - 1 && in->ptr[idx + 1] == '\'' && ! mri)
2704 +       {
2705 +         int base;
2706 +         int value;
2707 +         switch (in->ptr[idx])
2708 +           {
2709 +           case 'b':
2710 +           case 'B':
2711 +             base = 2;
2712 +             break;
2713 +           case 'q':
2714 +           case 'Q':
2715 +             base = 8;
2716 +             break;
2717 +           case 'h':
2718 +           case 'H':
2719 +             base = 16;
2720 +             break;
2721 +           case 'd':
2722 +           case 'D':
2723 +             base = 10;
2724 +             break;
2725 +           default:
2726 +             ERROR ((stderr, _("Illegal base character %c.\n"), in->ptr[idx]));
2727 +             base = 10;
2728 +             break;
2729 +           }
2730 +
2731 +         idx = sb_strtol (idx + 2, in, base, &value);
2732 +         sprintf (buffer, "%d", value);
2733 +         sb_add_string (out, buffer);
2734 +       }
2735 +      else if (ISFIRSTCHAR (in->ptr[idx]))
2736 +       {
2737 +         /* Copy entire names through quickly.  */
2738 +         sb_add_char (out, in->ptr[idx]);
2739 +         idx++;
2740 +         while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
2741 +           {
2742 +             sb_add_char (out, in->ptr[idx]);
2743 +             idx++;
2744 +           }
2745 +       }
2746 +      else if (is_flonum (idx, in))
2747 +       {
2748 +         idx = chew_flonum (idx, in, out);
2749 +       }
2750 +      else if (ISDIGIT (in->ptr[idx]))
2751 +       {
2752 +         int value;
2753 +         /* All numbers must start with a digit, let's chew it and
2754 +            spit out decimal.  */
2755 +         idx = sb_strtol (idx, in, radix, &value);
2756 +         sprintf (buffer, "%d", value);
2757 +         sb_add_string (out, buffer);
2758 +
2759 +         /* Skip all undigsested letters.  */
2760 +         while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
2761 +           {
2762 +             sb_add_char (out, in->ptr[idx]);
2763 +             idx++;
2764 +           }
2765 +       }
2766 +      else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
2767 +       {
2768 +         char tchar = in->ptr[idx];
2769 +         /* Copy entire names through quickly.  */
2770 +         sb_add_char (out, in->ptr[idx]);
2771 +         idx++;
2772 +         while (idx < in->len && in->ptr[idx] != tchar)
2773 +           {
2774 +             sb_add_char (out, in->ptr[idx]);
2775 +             idx++;
2776 +           }
2777 +       }
2778 +      else
2779 +       {
2780 +         /* Nothing special, just pass it through.  */
2781 +         sb_add_char (out, in->ptr[idx]);
2782 +         idx++;
2783 +       }
2784 +    }
2785 +
2786 +}
2787 +
2788 +/* .end  */
2789 +
2790 +static void
2791 +do_end (in)
2792 +     sb *in;
2793 +{
2794 +  had_end = 1;
2795 +  if (mri)
2796 +    fprintf (outfile, "%s\n", sb_name (in));
2797 +}
2798 +
2799 +/* .assign  */
2800 +
2801 +static void
2802 +do_assign (again, idx, in)
2803 +     int again;
2804 +     int idx;
2805 +     sb *in;
2806 +{
2807 +  /* Stick label in symbol table with following value.  */
2808 +  exp_t e;
2809 +  sb acc;
2810 +
2811 +  sb_new (&acc);
2812 +  idx = exp_parse (idx, in, &e);
2813 +  exp_string (&e, &acc);
2814 +  hash_add_to_string_table (&assign_hash_table, &label, &acc, again);
2815 +  sb_kill (&acc);
2816 +}
2817 +
2818 +/* .radix [b|q|d|h]  */
2819 +
2820 +static void
2821 +do_radix (ptr)
2822 +     sb *ptr;
2823 +{
2824 +  int idx = sb_skip_white (0, ptr);
2825 +  switch (ptr->ptr[idx])
2826 +    {
2827 +    case 'B':
2828 +    case 'b':
2829 +      radix = 2;
2830 +      break;
2831 +    case 'q':
2832 +    case 'Q':
2833 +      radix = 8;
2834 +      break;
2835 +    case 'd':
2836 +    case 'D':
2837 +      radix = 10;
2838 +      break;
2839 +    case 'h':
2840 +    case 'H':
2841 +      radix = 16;
2842 +      break;
2843 +    default:
2844 +      ERROR ((stderr, _("radix is %c must be one of b, q, d or h"), radix));
2845 +    }
2846 +}
2847 +
2848 +/* Parse off a .b, .w or .l.  */
2849 +
2850 +static int
2851 +get_opsize (idx, in, size)
2852 +     int idx;
2853 +     sb *in;
2854 +     int *size;
2855 +{
2856 +  *size = 4;
2857 +  if (in->ptr[idx] == '.')
2858 +    {
2859 +      idx++;
2860 +    }
2861 +  switch (in->ptr[idx])
2862 +    {
2863 +    case 'b':
2864 +    case 'B':
2865 +      *size = 1;
2866 +      break;
2867 +    case 'w':
2868 +    case 'W':
2869 +      *size = 2;
2870 +      break;
2871 +    case 'l':
2872 +    case 'L':
2873 +      *size = 4;
2874 +      break;
2875 +    case ' ':
2876 +    case '\t':
2877 +      break;
2878 +    default:
2879 +      ERROR ((stderr, _("size must be one of b, w or l, is %c.\n"), in->ptr[idx]));
2880 +      break;
2881 +    }
2882 +  idx++;
2883 +
2884 +  return idx;
2885 +}
2886 +
2887 +static int
2888 +eol (idx, line)
2889 +     int idx;
2890 +     sb *line;
2891 +{
2892 +  idx = sb_skip_white (idx, line);
2893 +  if (idx < line->len
2894 +      && ISCOMMENTCHAR(line->ptr[idx]))
2895 +    return 1;
2896 +  if (idx >= line->len)
2897 +    return 1;
2898 +  return 0;
2899 +}
2900 +
2901 +/* .data [.b|.w|.l] <data>*
2902 +    or d[bwl] <data>*  */
2903 +
2904 +static void
2905 +do_data (idx, in, size)
2906 +     int idx;
2907 +     sb *in;
2908 +     int size;
2909 +{
2910 +  int opsize = 4;
2911 +  char *opname = ".yikes!";
2912 +  sb acc;
2913 +  sb_new (&acc);
2914 +
2915 +  if (!size)
2916 +    {
2917 +      idx = get_opsize (idx, in, &opsize);
2918 +    }
2919 +  else
2920 +    {
2921 +      opsize = size;
2922 +    }
2923 +  switch (opsize)
2924 +    {
2925 +    case 4:
2926 +      opname = ".long";
2927 +      break;
2928 +    case 2:
2929 +      opname = ".short";
2930 +      break;
2931 +    case 1:
2932 +      opname = ".byte";
2933 +      break;
2934 +    }
2935 +
2936 +  fprintf (outfile, "%s\t", opname);
2937 +
2938 +  idx = sb_skip_white (idx, in);
2939 +
2940 +  if (alternate
2941 +      && idx < in->len
2942 +      && in->ptr[idx] == '"')
2943 +    {
2944 +      int i;
2945 +      idx = getstring (idx, in, &acc);
2946 +      for (i = 0; i < acc.len; i++)
2947 +       {
2948 +         if (i)
2949 +           fprintf (outfile, ",");
2950 +         fprintf (outfile, "%d", acc.ptr[i]);
2951 +       }
2952 +    }
2953 +  else
2954 +    {
2955 +      while (!eol (idx, in))
2956 +       {
2957 +         exp_t e;
2958 +         idx = exp_parse (idx, in, &e);
2959 +         exp_string (&e, &acc);
2960 +         sb_add_char (&acc, 0);
2961 +         fprintf (outfile, "%s", acc.ptr);
2962 +         if (idx < in->len && in->ptr[idx] == ',')
2963 +           {
2964 +             fprintf (outfile, ",");
2965 +             idx++;
2966 +           }
2967 +       }
2968 +    }
2969 +  sb_kill (&acc);
2970 +  sb_print_at (outfile, idx, in);
2971 +  fprintf (outfile, "\n");
2972 +}
2973 +
2974 +/* .datab [.b|.w|.l] <repeat>,<fill>  */
2975 +
2976 +static void
2977 +do_datab (idx, in)
2978 +     int idx;
2979 +     sb *in;
2980 +{
2981 +  int opsize;
2982 +  int repeat;
2983 +  int fill;
2984 +
2985 +  idx = get_opsize (idx, in, &opsize);
2986 +
2987 +  idx = exp_get_abs (_("datab repeat must be constant.\n"), idx, in, &repeat);
2988 +  idx = sb_skip_comma (idx, in);
2989 +  idx = exp_get_abs (_("datab data must be absolute.\n"), idx, in, &fill);
2990 +
2991 +  fprintf (outfile, ".fill\t%d,%d,%d\n", repeat, opsize, fill);
2992 +}
2993 +
2994 +/* .align <size>  */
2995 +
2996 +static void
2997 +do_align (idx, in)
2998 +     int idx;
2999 +     sb *in;
3000 +{
3001 +  int al, have_fill, fill;
3002 +
3003 +  idx = exp_get_abs (_("align needs absolute expression.\n"), idx, in, &al);
3004 +  idx = sb_skip_white (idx, in);
3005 +  have_fill = 0;
3006 +  fill = 0;
3007 +  if (! eol (idx, in))
3008 +    {
3009 +      idx = sb_skip_comma (idx, in);
3010 +      idx = exp_get_abs (_(".align needs absolute fill value.\n"), idx, in,
3011 +                        &fill);
3012 +      have_fill = 1;
3013 +    }
3014 +
3015 +  fprintf (outfile, ".align    %d", al);
3016 +  if (have_fill)
3017 +    fprintf (outfile, ",%d", fill);
3018 +  fprintf (outfile, "\n");
3019 +}
3020 +
3021 +/* .res[.b|.w|.l] <size>  */
3022 +
3023 +static void
3024 +do_res (idx, in, type)
3025 +     int idx;
3026 +     sb *in;
3027 +     int type;
3028 +{
3029 +  int size = 4;
3030 +  int count = 0;
3031 +
3032 +  idx = get_opsize (idx, in, &size);
3033 +  while (!eol (idx, in))
3034 +    {
3035 +      idx = sb_skip_white (idx, in);
3036 +      if (in->ptr[idx] == ',')
3037 +       idx++;
3038 +      idx = exp_get_abs (_("res needs absolute expression for fill count.\n"), idx, in, &count);
3039 +
3040 +      if (type == 'c' || type == 'z')
3041 +       count++;
3042 +
3043 +      fprintf (outfile, ".space        %d\n", count * size);
3044 +    }
3045 +}
3046 +
3047 +/* .export  */
3048 +
3049 +static void
3050 +do_export (in)
3051 +     sb *in;
3052 +{
3053 +  fprintf (outfile, ".global   %s\n", sb_name (in));
3054 +}
3055 +
3056 +/* .print [list] [nolist]  */
3057 +
3058 +static void
3059 +do_print (idx, in)
3060 +     int idx;
3061 +     sb *in;
3062 +{
3063 +  idx = sb_skip_white (idx, in);
3064 +  while (idx < in->len)
3065 +    {
3066 +      if (strncasecmp (in->ptr + idx, "LIST", 4) == 0)
3067 +       {
3068 +         fprintf (outfile, ".list\n");
3069 +         idx += 4;
3070 +       }
3071 +      else if (strncasecmp (in->ptr + idx, "NOLIST", 6) == 0)
3072 +       {
3073 +         fprintf (outfile, ".nolist\n");
3074 +         idx += 6;
3075 +       }
3076 +      idx++;
3077 +    }
3078 +}
3079 +
3080 +/* .head  */
3081 +
3082 +static void
3083 +do_heading (idx, in)
3084 +     int idx;
3085 +     sb *in;
3086 +{
3087 +  sb head;
3088 +  sb_new (&head);
3089 +  idx = getstring (idx, in, &head);
3090 +  fprintf (outfile, ".title    \"%s\"\n", sb_name (&head));
3091 +  sb_kill (&head);
3092 +}
3093 +
3094 +/* .page  */
3095 +
3096 +static void
3097 +do_page ()
3098 +{
3099 +  fprintf (outfile, ".eject\n");
3100 +}
3101 +
3102 +/* .form [lin=<value>] [col=<value>]  */
3103 +
3104 +static void
3105 +do_form (idx, in)
3106 +     int idx;
3107 +     sb *in;
3108 +{
3109 +  int lines = 60;
3110 +  int columns = 132;
3111 +  idx = sb_skip_white (idx, in);
3112 +
3113 +  while (idx < in->len)
3114 +    {
3115 +
3116 +      if (strncasecmp (in->ptr + idx, "LIN=", 4) == 0)
3117 +       {
3118 +         idx += 4;
3119 +         idx = exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx, in, &lines);
3120 +       }
3121 +
3122 +      if (strncasecmp (in->ptr + idx, _("COL="), 4) == 0)
3123 +       {
3124 +         idx += 4;
3125 +         idx = exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx, in, &columns);
3126 +       }
3127 +
3128 +      idx++;
3129 +    }
3130 +  fprintf (outfile, ".psize %d,%d\n", lines, columns);
3131 +
3132 +}
3133 +
3134 +/* Fetch string from the input stream,
3135 +   rules:
3136 +    'Bxyx<whitespace>          -> return 'Bxyza
3137 +    %<char>            -> return string of decimal value of x
3138 +    "<string>"         -> return string
3139 +    xyx<whitespace>     -> return xyz
3140 +*/
3141 +
3142 +static int
3143 +get_any_string (idx, in, out, expand, pretend_quoted)
3144 +     int idx;
3145 +     sb *in;
3146 +     sb *out;
3147 +     int expand;
3148 +     int pretend_quoted;
3149 +{
3150 +  sb_reset (out);
3151 +  idx = sb_skip_white (idx, in);
3152 +
3153 +  if (idx < in->len)
3154 +    {
3155 +      if (in->len > 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
3156 +       {
3157 +         while (!ISSEP (in->ptr[idx]))
3158 +           sb_add_char (out, in->ptr[idx++]);
3159 +       }
3160 +      else if (in->ptr[idx] == '%'
3161 +              && alternate
3162 +              && expand)
3163 +       {
3164 +         int val;
3165 +         char buf[20];
3166 +         /* Turns the next expression into a string.  */
3167 +         /* xgettext: no-c-format */
3168 +         idx = exp_get_abs (_("% operator needs absolute expression"),
3169 +                            idx + 1,
3170 +                            in,
3171 +                            &val);
3172 +         sprintf (buf, "%d", val);
3173 +         sb_add_string (out, buf);
3174 +       }
3175 +      else if (in->ptr[idx] == '"'
3176 +              || in->ptr[idx] == '<'
3177 +              || (alternate && in->ptr[idx] == '\''))
3178 +       {
3179 +         if (alternate && expand)
3180 +           {
3181 +             /* Keep the quotes.  */
3182 +             sb_add_char (out, '\"');
3183 +
3184 +             idx = getstring (idx, in, out);
3185 +             sb_add_char (out, '\"');
3186 +
3187 +           }
3188 +         else
3189 +           {
3190 +             idx = getstring (idx, in, out);
3191 +           }
3192 +       }
3193 +      else
3194 +       {
3195 +         while (idx < in->len
3196 +                && (in->ptr[idx] == '"'
3197 +                    || in->ptr[idx] == '\''
3198 +                    || pretend_quoted
3199 +                    || !ISSEP (in->ptr[idx])))
3200 +           {
3201 +             if (in->ptr[idx] == '"'
3202 +                 || in->ptr[idx] == '\'')
3203 +               {
3204 +                 char tchar = in->ptr[idx];
3205 +                 sb_add_char (out, in->ptr[idx++]);
3206 +                 while (idx < in->len
3207 +                        && in->ptr[idx] != tchar)
3208 +                   sb_add_char (out, in->ptr[idx++]);
3209 +                 if (idx == in->len)
3210 +                   return idx;
3211 +               }
3212 +             sb_add_char (out, in->ptr[idx++]);
3213 +           }
3214 +       }
3215 +    }
3216 +
3217 +  return idx;
3218 +}
3219 +
3220 +/* Skip along sb in starting at idx, suck off whitespace a ( and more
3221 +   whitespace.  Return the idx of the next char.  */
3222 +
3223 +static int
3224 +skip_openp (idx, in)
3225 +     int idx;
3226 +     sb *in;
3227 +{
3228 +  idx = sb_skip_white (idx, in);
3229 +  if (in->ptr[idx] != '(')
3230 +    ERROR ((stderr, _("misplaced ( .\n")));
3231 +  idx = sb_skip_white (idx + 1, in);
3232 +  return idx;
3233 +}
3234 +
3235 +/* Skip along sb in starting at idx, suck off whitespace a ) and more
3236 +   whitespace.  Return the idx of the next char.  */
3237 +
3238 +static int
3239 +skip_closep (idx, in)
3240 +     int idx;
3241 +     sb *in;
3242 +{
3243 +  idx = sb_skip_white (idx, in);
3244 +  if (in->ptr[idx] != ')')
3245 +    ERROR ((stderr, _("misplaced ).\n")));
3246 +  idx = sb_skip_white (idx + 1, in);
3247 +  return idx;
3248 +}
3249 +
3250 +/* .len  */
3251 +
3252 +static int
3253 +dolen (idx, in, out)
3254 +     int idx;
3255 +     sb *in;
3256 +     sb *out;
3257 +{
3258 +
3259 +  sb stringout;
3260 +  char buffer[10];
3261 +
3262 +  sb_new (&stringout);
3263 +  idx = skip_openp (idx, in);
3264 +  idx = get_and_process (idx, in, &stringout);
3265 +  idx = skip_closep (idx, in);
3266 +  sprintf (buffer, "%d", stringout.len);
3267 +  sb_add_string (out, buffer);
3268 +
3269 +  sb_kill (&stringout);
3270 +  return idx;
3271 +}
3272 +
3273 +/* .instr  */
3274 +
3275 +static int
3276 +doinstr (idx, in, out)
3277 +     int idx;
3278 +     sb *in;
3279 +     sb *out;
3280 +{
3281 +  sb string;
3282 +  sb search;
3283 +  int i;
3284 +  int start;
3285 +  int res;
3286 +  char buffer[10];
3287 +
3288 +  sb_new (&string);
3289 +  sb_new (&search);
3290 +  idx = skip_openp (idx, in);
3291 +  idx = get_and_process (idx, in, &string);
3292 +  idx = sb_skip_comma (idx, in);
3293 +  idx = get_and_process (idx, in, &search);
3294 +  idx = sb_skip_comma (idx, in);
3295 +  if (ISDIGIT (in->ptr[idx]))
3296 +    {
3297 +      idx = exp_get_abs (_(".instr needs absolute expresson.\n"), idx, in, &start);
3298 +    }
3299 +  else
3300 +    {
3301 +      start = 0;
3302 +    }
3303 +  idx = skip_closep (idx, in);
3304 +  res = -1;
3305 +  for (i = start; i < string.len; i++)
3306 +    {
3307 +      if (strncmp (string.ptr + i, search.ptr, search.len) == 0)
3308 +       {
3309 +         res = i;
3310 +         break;
3311 +       }
3312 +    }
3313 +  sprintf (buffer, "%d", res);
3314 +  sb_add_string (out, buffer);
3315 +  sb_kill (&string);
3316 +  sb_kill (&search);
3317 +  return idx;
3318 +}
3319 +
3320 +static int
3321 +dosubstr (idx, in, out)
3322 +     int idx;
3323 +     sb *in;
3324 +     sb *out;
3325 +{
3326 +  sb string;
3327 +  int pos;
3328 +  int len;
3329 +  sb_new (&string);
3330 +
3331 +  idx = skip_openp (idx, in);
3332 +  idx = get_and_process (idx, in, &string);
3333 +  idx = sb_skip_comma (idx, in);
3334 +  idx = exp_get_abs (_("need absolute position.\n"), idx, in, &pos);
3335 +  idx = sb_skip_comma (idx, in);
3336 +  idx = exp_get_abs (_("need absolute length.\n"), idx, in, &len);
3337 +  idx = skip_closep (idx, in);
3338 +
3339 +  if (len < 0 || pos < 0 ||
3340 +      pos > string.len
3341 +      || pos + len > string.len)
3342 +    {
3343 +      sb_add_string (out, " ");
3344 +    }
3345 +  else
3346 +    {
3347 +      sb_add_char (out, '"');
3348 +      while (len > 0)
3349 +       {
3350 +         sb_add_char (out, string.ptr[pos++]);
3351 +         len--;
3352 +       }
3353 +      sb_add_char (out, '"');
3354 +    }
3355 +  sb_kill (&string);
3356 +  return idx;
3357 +}
3358 +
3359 +/* Scan line, change tokens in the hash table to their replacements.  */
3360 +
3361 +static void
3362 +process_assigns (idx, in, buf)
3363 +     int idx;
3364 +     sb *in;
3365 +     sb *buf;
3366 +{
3367 +  while (idx < in->len)
3368 +    {
3369 +      hash_entry *ptr;
3370 +      if (in->ptr[idx] == '\\'
3371 +         && idx + 1 < in->len
3372 +         && in->ptr[idx + 1] == '(')
3373 +       {
3374 +         do
3375 +           {
3376 +             sb_add_char (buf, in->ptr[idx]);
3377 +             idx++;
3378 +           }
3379 +         while (idx < in->len && in->ptr[idx - 1] != ')');
3380 +       }
3381 +      else if (in->ptr[idx] == '\\'
3382 +         && idx + 1 < in->len
3383 +         && in->ptr[idx + 1] == '&')
3384 +       {
3385 +         idx = condass_lookup_name (in, idx + 2, buf, 1);
3386 +       }
3387 +      else if (in->ptr[idx] == '\\'
3388 +              && idx + 1 < in->len
3389 +              && in->ptr[idx + 1] == '$')
3390 +       {
3391 +         idx = condass_lookup_name (in, idx + 2, buf, 0);
3392 +       }
3393 +      else if (idx + 3 < in->len
3394 +              && in->ptr[idx] == '.'
3395 +              && TOUPPER (in->ptr[idx + 1]) == 'L'
3396 +              && TOUPPER (in->ptr[idx + 2]) == 'E'
3397 +              && TOUPPER (in->ptr[idx + 3]) == 'N')
3398 +       idx = dolen (idx + 4, in, buf);
3399 +      else if (idx + 6 < in->len
3400 +              && in->ptr[idx] == '.'
3401 +              && TOUPPER (in->ptr[idx + 1]) == 'I'
3402 +              && TOUPPER (in->ptr[idx + 2]) == 'N'
3403 +              && TOUPPER (in->ptr[idx + 3]) == 'S'
3404 +              && TOUPPER (in->ptr[idx + 4]) == 'T'
3405 +              && TOUPPER (in->ptr[idx + 5]) == 'R')
3406 +       idx = doinstr (idx + 6, in, buf);
3407 +      else if (idx + 7 < in->len
3408 +              && in->ptr[idx] == '.'
3409 +              && TOUPPER (in->ptr[idx + 1]) == 'S'
3410 +              && TOUPPER (in->ptr[idx + 2]) == 'U'
3411 +              && TOUPPER (in->ptr[idx + 3]) == 'B'
3412 +              && TOUPPER (in->ptr[idx + 4]) == 'S'
3413 +              && TOUPPER (in->ptr[idx + 5]) == 'T'
3414 +              && TOUPPER (in->ptr[idx + 6]) == 'R')
3415 +       idx = dosubstr (idx + 7, in, buf);
3416 +      else if (ISFIRSTCHAR (in->ptr[idx]))
3417 +       {
3418 +         /* May be a simple name subsitution, see if we have a word.  */
3419 +         sb acc;
3420 +         int cur = idx + 1;
3421 +         while (cur < in->len
3422 +                && (ISNEXTCHAR (in->ptr[cur])))
3423 +           cur++;
3424 +
3425 +         sb_new (&acc);
3426 +         sb_add_buffer (&acc, in->ptr + idx, cur - idx);
3427 +         ptr = hash_lookup (&assign_hash_table, &acc);
3428 +         if (ptr)
3429 +           {
3430 +             /* Found a definition for it.  */
3431 +             sb_add_sb (buf, &ptr->value.s);
3432 +           }
3433 +         else
3434 +           {
3435 +             /* No definition, just copy the word.  */
3436 +             sb_add_sb (buf, &acc);
3437 +           }
3438 +         sb_kill (&acc);
3439 +         idx = cur;
3440 +       }
3441 +      else
3442 +       {
3443 +         sb_add_char (buf, in->ptr[idx++]);
3444 +       }
3445 +    }
3446 +}
3447 +
3448 +static int
3449 +get_and_process (idx, in, out)
3450 +     int idx;
3451 +     sb *in;
3452 +     sb *out;
3453 +{
3454 +  sb t;
3455 +  sb_new (&t);
3456 +  idx = get_any_string (idx, in, &t, 1, 0);
3457 +  process_assigns (0, &t, out);
3458 +  sb_kill (&t);
3459 +  return idx;
3460 +}
3461 +
3462 +static void
3463 +process_file ()
3464 +{
3465 +  sb line;
3466 +  sb t1, t2;
3467 +  sb acc;
3468 +  sb label_in;
3469 +  int more;
3470 +
3471 +  sb_new (&line);
3472 +  sb_new (&t1);
3473 +  sb_new (&t2);
3474 +  sb_new (&acc);
3475 +  sb_new (&label_in);
3476 +  sb_reset (&line);
3477 +  more = get_line (&line);
3478 +  while (more)
3479 +    {
3480 +      /* Find any label and pseudo op that we're intested in.  */
3481 +      int l;
3482 +      if (line.len == 0)
3483 +       {
3484 +         if (condass_on ())
3485 +           fprintf (outfile, "\n");
3486 +       }
3487 +      else if (mri
3488 +              && (line.ptr[0] == '*'
3489 +                  || line.ptr[0] == '!'))
3490 +       {
3491 +         /* MRI line comment.  */
3492 +         fprintf (outfile, "%s", sb_name (&line));
3493 +       }
3494 +      else
3495 +       {
3496 +         l = grab_label (&line, &label_in);
3497 +         sb_reset (&label);
3498 +
3499 +         if (line.ptr[l] == ':')
3500 +           l++;
3501 +         while (ISWHITE (line.ptr[l]) && l < line.len)
3502 +           l++;
3503 +
3504 +         if (label_in.len)
3505 +           {
3506 +             int do_assigns;
3507 +
3508 +             /* Munge the label, unless this is EQU or ASSIGN.  */
3509 +             do_assigns = 1;
3510 +             if (l < line.len
3511 +                 && (line.ptr[l] == '.' || alternate || mri))
3512 +               {
3513 +                 int lx = l;
3514 +
3515 +                 if (line.ptr[lx] == '.')
3516 +                   ++lx;
3517 +                 if (lx + 3 <= line.len
3518 +                     && strncasecmp ("EQU", line.ptr + lx, 3) == 0
3519 +                     && (lx + 3 == line.len
3520 +                         || ! ISFIRSTCHAR (line.ptr[lx + 3])))
3521 +                   do_assigns = 0;
3522 +                 else if (lx + 6 <= line.len
3523 +                          && strncasecmp ("ASSIGN", line.ptr + lx, 6) == 0
3524 +                          && (lx + 6 == line.len
3525 +                              || ! ISFIRSTCHAR (line.ptr[lx + 6])))
3526 +                   do_assigns = 0;
3527 +               }
3528 +
3529 +             if (do_assigns)
3530 +               process_assigns (0, &label_in, &label);
3531 +             else
3532 +               sb_add_sb (&label, &label_in);
3533 +           }
3534 +
3535 +         if (l < line.len)
3536 +           {
3537 +             if (process_pseudo_op (l, &line, &acc))
3538 +               {
3539 +
3540 +               }
3541 +             else if (condass_on ())
3542 +               {
3543 +                 if (macro_op (l, &line))
3544 +                   {
3545 +
3546 +                   }
3547 +                 else
3548 +                   {
3549 +                     {
3550 +                       if (label.len)
3551 +                         {
3552 +                           fprintf (outfile, "%s:\t", sb_name (&label));
3553 +                         }
3554 +                       else
3555 +                         fprintf (outfile, "\t");
3556 +                       sb_reset (&t1);
3557 +                       process_assigns (l, &line, &t1);
3558 +                       sb_reset (&t2);
3559 +                       change_base (0, &t1, &t2);
3560 +                       fprintf (outfile, "%s\n", sb_name (&t2));
3561 +                     }
3562 +                   }
3563 +               }
3564 +           }
3565 +         else
3566 +           {
3567 +             /* Only a label on this line.  */
3568 +             if (label.len && condass_on ())
3569 +               {
3570 +                 fprintf (outfile, "%s:\n", sb_name (&label));
3571 +               }
3572 +           }
3573 +       }
3574 +
3575 +      if (had_end)
3576 +       break;
3577 +      sb_reset (&line);
3578 +      more = get_line (&line);
3579 +    }
3580 +
3581 +  if (!had_end && !mri)
3582 +    WARNING ((stderr, _("END missing from end of file.\n")));
3583 +}
3584 +
3585 +static void
3586 +free_old_entry (ptr)
3587 +     hash_entry *ptr;
3588 +{
3589 +  if (ptr)
3590 +    {
3591 +      if (ptr->type == hash_string)
3592 +       sb_kill (&ptr->value.s);
3593 +    }
3594 +}
3595 +
3596 +/* name: .ASSIGNA <value>  */
3597 +
3598 +static void
3599 +do_assigna (idx, in)
3600 +     int idx;
3601 +     sb *in;
3602 +{
3603 +  sb tmp;
3604 +  int val;
3605 +  sb_new (&tmp);
3606 +
3607 +  process_assigns (idx, in, &tmp);
3608 +  idx = exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp, &val);
3609 +
3610 +  if (!label.len)
3611 +    {
3612 +      ERROR ((stderr, _(".ASSIGNA without label.\n")));
3613 +    }
3614 +  else
3615 +    {
3616 +      hash_entry *ptr = hash_create (&vars, &label);
3617 +      free_old_entry (ptr);
3618 +      ptr->type = hash_integer;
3619 +      ptr->value.i = val;
3620 +    }
3621 +  sb_kill (&tmp);
3622 +}
3623 +
3624 +/* name: .ASSIGNC <string>  */
3625 +
3626 +static void
3627 +do_assignc (idx, in)
3628 +     int idx;
3629 +     sb *in;
3630 +{
3631 +  sb acc;
3632 +  sb_new (&acc);
3633 +  idx = getstring (idx, in, &acc);
3634 +
3635 +  if (!label.len)
3636 +    {
3637 +      ERROR ((stderr, _(".ASSIGNS without label.\n")));
3638 +    }
3639 +  else
3640 +    {
3641 +      hash_entry *ptr = hash_create (&vars, &label);
3642 +      free_old_entry (ptr);
3643 +      ptr->type = hash_string;
3644 +      sb_new (&ptr->value.s);
3645 +      sb_add_sb (&ptr->value.s, &acc);
3646 +    }
3647 +  sb_kill (&acc);
3648 +}
3649 +
3650 +/* name: .REG (reg)  */
3651 +
3652 +static void
3653 +do_reg (idx, in)
3654 +     int idx;
3655 +     sb *in;
3656 +{
3657 +  /* Remove reg stuff from inside parens.  */
3658 +  sb what;
3659 +  if (!mri)
3660 +    idx = skip_openp (idx, in);
3661 +  else
3662 +    idx = sb_skip_white (idx, in);
3663 +  sb_new (&what);
3664 +  while (idx < in->len
3665 +        && (mri
3666 +            ? ! eol (idx, in)
3667 +            : in->ptr[idx] != ')'))
3668 +    {
3669 +      sb_add_char (&what, in->ptr[idx]);
3670 +      idx++;
3671 +    }
3672 +  hash_add_to_string_table (&assign_hash_table, &label, &what, 1);
3673 +  sb_kill (&what);
3674 +}
3675 +
3676 +static int
3677 +condass_lookup_name (inbuf, idx, out, warn)
3678 +     sb *inbuf;
3679 +     int idx;
3680 +     sb *out;
3681 +     int warn;
3682 +{
3683 +  hash_entry *ptr;
3684 +  sb condass_acc;
3685 +  sb_new (&condass_acc);
3686 +
3687 +  while (idx < inbuf->len
3688 +        && ISNEXTCHAR (inbuf->ptr[idx]))
3689 +    {
3690 +      sb_add_char (&condass_acc, inbuf->ptr[idx++]);
3691 +    }
3692 +
3693 +  if (inbuf->ptr[idx] == '\'')
3694 +    idx++;
3695 +  ptr = hash_lookup (&vars, &condass_acc);
3696 +
3697 +  if (!ptr)
3698 +    {
3699 +      if (warn)
3700 +       {
3701 +         WARNING ((stderr, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc)));
3702 +       }
3703 +      else
3704 +       {
3705 +         sb_add_string (out, "0");
3706 +       }
3707 +    }
3708 +  else
3709 +    {
3710 +      if (ptr->type == hash_integer)
3711 +       {
3712 +         char buffer[30];
3713 +         sprintf (buffer, "%d", ptr->value.i);
3714 +         sb_add_string (out, buffer);
3715 +       }
3716 +      else
3717 +       {
3718 +         sb_add_sb (out, &ptr->value.s);
3719 +       }
3720 +    }
3721 +  sb_kill (&condass_acc);
3722 +  return idx;
3723 +}
3724 +
3725 +#define EQ 1
3726 +#define NE 2
3727 +#define GE 3
3728 +#define LT 4
3729 +#define LE 5
3730 +#define GT 6
3731 +#define NEVER 7
3732 +
3733 +static int
3734 +whatcond (idx, in, val)
3735 +     int idx;
3736 +     sb *in;
3737 +     int *val;
3738 +{
3739 +  int cond;
3740 +
3741 +  idx = sb_skip_white (idx, in);
3742 +  cond = NEVER;
3743 +  if (idx + 1 < in->len)
3744 +    {
3745 +      char *p;
3746 +      char a, b;
3747 +
3748 +      p = in->ptr + idx;
3749 +      a = TOUPPER (p[0]);
3750 +      b = TOUPPER (p[1]);
3751 +      if (a == 'E' && b == 'Q')
3752 +       cond = EQ;
3753 +      else if (a == 'N' && b == 'E')
3754 +       cond = NE;
3755 +      else if (a == 'L' && b == 'T')
3756 +       cond = LT;
3757 +      else if (a == 'L' && b == 'E')
3758 +       cond = LE;
3759 +      else if (a == 'G' && b == 'T')
3760 +       cond = GT;
3761 +      else if (a == 'G' && b == 'E')
3762 +       cond = GE;
3763 +    }
3764 +  if (cond == NEVER)
3765 +    {
3766 +      ERROR ((stderr, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
3767 +      cond = NEVER;
3768 +    }
3769 +  idx = sb_skip_white (idx + 2, in);
3770 +  *val = cond;
3771 +  return idx;
3772 +}
3773 +
3774 +static int
3775 +istrue (idx, in)
3776 +     int idx;
3777 +     sb *in;
3778 +{
3779 +  int res;
3780 +  sb acc_a;
3781 +  sb cond;
3782 +  sb acc_b;
3783 +  sb_new (&acc_a);
3784 +  sb_new (&cond);
3785 +  sb_new (&acc_b);
3786 +  idx = sb_skip_white (idx, in);
3787 +
3788 +  if (in->ptr[idx] == '"')
3789 +    {
3790 +      int cond;
3791 +      int same;
3792 +      /* This is a string comparision.  */
3793 +      idx = getstring (idx, in, &acc_a);
3794 +      idx = whatcond (idx, in, &cond);
3795 +      idx = getstring (idx, in, &acc_b);
3796 +      same = acc_a.len == acc_b.len
3797 +       && (strncmp (acc_a.ptr, acc_b.ptr, acc_a.len) == 0);
3798 +
3799 +      if (cond != EQ && cond != NE)
3800 +       {
3801 +         ERROR ((stderr, _("Comparison operator for strings must be EQ or NE\n")));
3802 +         res = 0;
3803 +       }
3804 +      else
3805 +       res = (cond != EQ) ^ same;
3806 +    }
3807 +  else
3808 +    /* This is a numeric expression.  */
3809 +    {
3810 +      int vala;
3811 +      int valb;
3812 +      int cond;
3813 +      idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &vala);
3814 +      idx = whatcond (idx, in, &cond);
3815 +      idx = sb_skip_white (idx, in);
3816 +      if (in->ptr[idx] == '"')
3817 +       {
3818 +         WARNING ((stderr, _("String compared against expression.\n")));
3819 +         res = 0;
3820 +       }
3821 +      else
3822 +       {
3823 +         idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &valb);
3824 +         switch (cond)
3825 +           {
3826 +           default:
3827 +             res = 42;
3828 +             break;
3829 +           case EQ:
3830 +             res = vala == valb;
3831 +             break;
3832 +           case NE:
3833 +             res = vala != valb;
3834 +             break;
3835 +           case LT:
3836 +             res = vala < valb;
3837 +             break;
3838 +           case LE:
3839 +             res = vala <= valb;
3840 +             break;
3841 +           case GT:
3842 +             res = vala > valb;
3843 +             break;
3844 +           case GE:
3845 +             res = vala >= valb;
3846 +             break;
3847 +           case NEVER:
3848 +             res = 0;
3849 +             break;
3850 +           }
3851 +       }
3852 +    }
3853 +
3854 +  sb_kill (&acc_a);
3855 +  sb_kill (&cond);
3856 +  sb_kill (&acc_b);
3857 +  return res;
3858 +}
3859 +
3860 +/* .AIF  */
3861 +
3862 +static void
3863 +do_aif (idx, in)
3864 +     int idx;
3865 +     sb *in;
3866 +{
3867 +  if (ifi >= IFNESTING)
3868 +    {
3869 +      FATAL ((stderr, _("AIF nesting unreasonable.\n")));
3870 +    }
3871 +  ifi++;
3872 +  ifstack[ifi].on = ifstack[ifi - 1].on ? istrue (idx, in) : 0;
3873 +  ifstack[ifi].hadelse = 0;
3874 +}
3875 +
3876 +/* .AELSE  */
3877 +
3878 +static void
3879 +do_aelse ()
3880 +{
3881 +  ifstack[ifi].on = ifstack[ifi - 1].on ? !ifstack[ifi].on : 0;
3882 +  if (ifstack[ifi].hadelse)
3883 +    {
3884 +      ERROR ((stderr, _("Multiple AELSEs in AIF.\n")));
3885 +    }
3886 +  ifstack[ifi].hadelse = 1;
3887 +}
3888 +
3889 +/* .AENDI  */
3890 +
3891 +static void
3892 +do_aendi ()
3893 +{
3894 +  if (ifi != 0)
3895 +    {
3896 +      ifi--;
3897 +    }
3898 +  else
3899 +    {
3900 +      ERROR ((stderr, _("AENDI without AIF.\n")));
3901 +    }
3902 +}
3903 +
3904 +static int
3905 +condass_on ()
3906 +{
3907 +  return ifstack[ifi].on;
3908 +}
3909 +
3910 +/* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT.  */
3911 +
3912 +static void
3913 +do_if (idx, in, cond)
3914 +     int idx;
3915 +     sb *in;
3916 +     int cond;
3917 +{
3918 +  int val;
3919 +  int res;
3920 +
3921 +  if (ifi >= IFNESTING)
3922 +    {
3923 +      FATAL ((stderr, _("IF nesting unreasonable.\n")));
3924 +    }
3925 +
3926 +  idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"),
3927 +                    idx, in, &val);
3928 +  switch (cond)
3929 +    {
3930 +    default:
3931 +    case EQ: res = val == 0; break;
3932 +    case NE: res = val != 0; break;
3933 +    case LT: res = val <  0; break;
3934 +    case LE: res = val <= 0; break;
3935 +    case GE: res = val >= 0; break;
3936 +    case GT: res = val >  0; break;
3937 +    }
3938 +
3939 +  ifi++;
3940 +  ifstack[ifi].on = ifstack[ifi - 1].on ? res : 0;
3941 +  ifstack[ifi].hadelse = 0;
3942 +}
3943 +
3944 +/* Get a string for the MRI IFC or IFNC pseudo-ops.  */
3945 +
3946 +static int
3947 +get_mri_string (idx, in, val, terminator)
3948 +     int idx;
3949 +     sb *in;
3950 +     sb *val;
3951 +     int terminator;
3952 +{
3953 +  idx = sb_skip_white (idx, in);
3954 +
3955 +  if (idx < in->len
3956 +      && in->ptr[idx] == '\'')
3957 +    {
3958 +      sb_add_char (val, '\'');
3959 +      for (++idx; idx < in->len; ++idx)
3960 +       {
3961 +         sb_add_char (val, in->ptr[idx]);
3962 +         if (in->ptr[idx] == '\'')
3963 +           {
3964 +             ++idx;
3965 +             if (idx >= in->len
3966 +                 || in->ptr[idx] != '\'')
3967 +               break;
3968 +           }
3969 +       }
3970 +      idx = sb_skip_white (idx, in);
3971 +    }
3972 +  else
3973 +    {
3974 +      int i;
3975 +
3976 +      while (idx < in->len
3977 +            && in->ptr[idx] != terminator)
3978 +       {
3979 +         sb_add_char (val, in->ptr[idx]);
3980 +         ++idx;
3981 +       }
3982 +      i = val->len - 1;
3983 +      while (i >= 0 && ISWHITE (val->ptr[i]))
3984 +       --i;
3985 +      val->len = i + 1;
3986 +    }
3987 +
3988 +  return idx;
3989 +}
3990 +
3991 +/* MRI IFC, IFNC  */
3992 +
3993 +static void
3994 +do_ifc (idx, in, ifnc)
3995 +     int idx;
3996 +     sb *in;
3997 +     int ifnc;
3998 +{
3999 +  sb first;
4000 +  sb second;
4001 +  int res;
4002 +
4003 +  if (ifi >= IFNESTING)
4004 +    {
4005 +      FATAL ((stderr, _("IF nesting unreasonable.\n")));
4006 +    }
4007 +
4008 +  sb_new (&first);
4009 +  sb_new (&second);
4010 +
4011 +  idx = get_mri_string (idx, in, &first, ',');
4012 +
4013 +  if (idx >= in->len || in->ptr[idx] != ',')
4014 +    {
4015 +      ERROR ((stderr, _("Bad format for IF or IFNC.\n")));
4016 +      return;
4017 +    }
4018 +
4019 +  idx = get_mri_string (idx + 1, in, &second, ';');
4020 +
4021 +  res = (first.len == second.len
4022 +        && strncmp (first.ptr, second.ptr, first.len) == 0);
4023 +  res ^= ifnc;
4024 +
4025 +  ifi++;
4026 +  ifstack[ifi].on = ifstack[ifi - 1].on ? res : 0;
4027 +  ifstack[ifi].hadelse = 0;
4028 +}
4029 +
4030 +/* .ENDR  */
4031 +
4032 +static void
4033 +do_aendr ()
4034 +{
4035 +  if (!mri)
4036 +    ERROR ((stderr, _("AENDR without a AREPEAT.\n")));
4037 +  else
4038 +    ERROR ((stderr, _("ENDR without a REPT.\n")));
4039 +}
4040 +
4041 +/* .AWHILE  */
4042 +
4043 +static void
4044 +do_awhile (idx, in)
4045 +     int idx;
4046 +     sb *in;
4047 +{
4048 +  int line = linecount ();
4049 +  sb exp;
4050 +  sb sub;
4051 +  int doit;
4052 +
4053 +  sb_new (&sub);
4054 +  sb_new (&exp);
4055 +
4056 +  process_assigns (idx, in, &exp);
4057 +  doit = istrue (0, &exp);
4058 +
4059 +  if (! buffer_and_nest ("AWHILE", "AENDW", &sub, get_line))
4060 +    FATAL ((stderr, _("AWHILE without a AENDW at %d.\n"), line - 1));
4061 +
4062 +  /* Turn
4063 +       .AWHILE exp
4064 +            foo
4065 +       .AENDW
4066 +     into
4067 +        foo
4068 +       .AWHILE exp
4069 +       foo
4070 +       .ENDW
4071 +  */
4072 +
4073 +  if (doit)
4074 +    {
4075 +      int index = include_next_index ();
4076 +
4077 +      sb copy;
4078 +      sb_new (&copy);
4079 +      sb_add_sb (&copy, &sub);
4080 +      sb_add_sb (&copy, in);
4081 +      sb_add_string (&copy, "\n");
4082 +      sb_add_sb (&copy, &sub);
4083 +      sb_add_string (&copy, "\t.AENDW\n");
4084 +      /* Push another WHILE.  */
4085 +      include_buf (&exp, &copy, include_while, index);
4086 +      sb_kill (&copy);
4087 +    }
4088 +  sb_kill (&exp);
4089 +  sb_kill (&sub);
4090 +}
4091 +
4092 +/* .AENDW  */
4093 +
4094 +static void
4095 +do_aendw ()
4096 +{
4097 +  ERROR ((stderr, _("AENDW without a AENDW.\n")));
4098 +}
4099 +
4100 +/* .EXITM
4101 +
4102 +   Pop things off the include stack until the type and index changes.  */
4103 +
4104 +static void
4105 +do_exitm ()
4106 +{
4107 +  include_type type = sp->type;
4108 +  if (type == include_repeat
4109 +      || type == include_while
4110 +      || type == include_macro)
4111 +    {
4112 +      int index = sp->index;
4113 +      include_pop ();
4114 +      while (sp->index == index
4115 +            && sp->type == type)
4116 +       {
4117 +         include_pop ();
4118 +       }
4119 +    }
4120 +}
4121 +
4122 +/* .AREPEAT  */
4123 +
4124 +static void
4125 +do_arepeat (idx, in)
4126 +     int idx;
4127 +     sb *in;
4128 +{
4129 +  int line = linecount ();
4130 +  sb exp;                      /* Buffer with expression in it.  */
4131 +  sb copy;                     /* Expanded repeat block.  */
4132 +  sb sub;                      /* Contents of AREPEAT.  */
4133 +  int rc;
4134 +  int ret;
4135 +  char buffer[30];
4136 +
4137 +  sb_new (&exp);
4138 +  sb_new (&copy);
4139 +  sb_new (&sub);
4140 +  process_assigns (idx, in, &exp);
4141 +  idx = exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp, &rc);
4142 +  if (!mri)
4143 +    ret = buffer_and_nest ("AREPEAT", "AENDR", &sub, get_line);
4144 +  else
4145 +    ret = buffer_and_nest ("REPT", "ENDR", &sub, get_line);
4146 +  if (! ret)
4147 +    FATAL ((stderr, _("AREPEAT without a AENDR at %d.\n"), line - 1));
4148 +  if (rc > 0)
4149 +    {
4150 +      /* Push back the text following the repeat, and another repeat block
4151 +        so
4152 +        .AREPEAT 20
4153 +        foo
4154 +        .AENDR
4155 +        gets turned into
4156 +        foo
4157 +        .AREPEAT 19
4158 +        foo
4159 +        .AENDR
4160 +      */
4161 +      int index = include_next_index ();
4162 +      sb_add_sb (&copy, &sub);
4163 +      if (rc > 1)
4164 +       {
4165 +         if (!mri)
4166 +           sprintf (buffer, "\t.AREPEAT        %d\n", rc - 1);
4167 +         else
4168 +           sprintf (buffer, "\tREPT    %d\n", rc - 1);
4169 +         sb_add_string (&copy, buffer);
4170 +         sb_add_sb (&copy, &sub);
4171 +         if (!mri)
4172 +           sb_add_string (&copy, "     .AENDR\n");
4173 +         else
4174 +           sb_add_string (&copy, "     ENDR\n");
4175 +       }
4176 +
4177 +      include_buf (&exp, &copy, include_repeat, index);
4178 +    }
4179 +  sb_kill (&exp);
4180 +  sb_kill (&sub);
4181 +  sb_kill (&copy);
4182 +}
4183 +
4184 +/* .ENDM  */
4185 +
4186 +static void
4187 +do_endm ()
4188 +{
4189 +  ERROR ((stderr, _(".ENDM without a matching .MACRO.\n")));
4190 +}
4191 +
4192 +/* MRI IRP pseudo-op.  */
4193 +
4194 +static void
4195 +do_irp (idx, in, irpc)
4196 +     int idx;
4197 +     sb *in;
4198 +     int irpc;
4199 +{
4200 +  const char *err;
4201 +  sb out;
4202 +
4203 +  sb_new (&out);
4204 +
4205 +  err = expand_irp (irpc, idx, in, &out, get_line, comment_char);
4206 +  if (err != NULL)
4207 +    ERROR ((stderr, "%s\n", err));
4208 +
4209 +  fprintf (outfile, "%s", sb_terminate (&out));
4210 +
4211 +  sb_kill (&out);
4212 +}
4213 +
4214 +/* Macro processing.  */
4215 +
4216 +/* Parse off LOCAL n1, n2,... Invent a label name for it.  */
4217 +
4218 +static void
4219 +do_local (idx, line)
4220 +     int idx ATTRIBUTE_UNUSED;
4221 +     sb *line ATTRIBUTE_UNUSED;
4222 +{
4223 +  ERROR ((stderr, _("LOCAL outside of MACRO")));
4224 +}
4225 +
4226 +static void
4227 +do_macro (idx, in)
4228 +     int idx;
4229 +     sb *in;
4230 +{
4231 +  const char *err;
4232 +  int line = linecount ();
4233 +
4234 +  err = define_macro (idx, in, &label, get_line, "[gasp]", line, (const char **) NULL);
4235 +  if (err != NULL)
4236 +    ERROR ((stderr, _("macro at line %d: %s\n"), line - 1, err));
4237 +}
4238 +
4239 +static int
4240 +macro_op (idx, in)
4241 +     int idx;
4242 +     sb *in;
4243 +{
4244 +  const char *err;
4245 +  sb out;
4246 +  sb name;
4247 +
4248 +  if (! macro_defined)
4249 +    return 0;
4250 +
4251 +  sb_terminate (in);
4252 +  if (! check_macro (in->ptr + idx, &out, comment_char, &err, NULL))
4253 +    return 0;
4254 +
4255 +  if (err != NULL)
4256 +    ERROR ((stderr, "%s\n", err));
4257 +
4258 +  sb_new (&name);
4259 +  sb_add_string (&name, _("macro expansion"));
4260 +
4261 +  include_buf (&name, &out, include_macro, include_next_index ());
4262 +
4263 +  sb_kill (&name);
4264 +  sb_kill (&out);
4265 +
4266 +  return 1;
4267 +}
4268 +
4269 +/* String handling.  */
4270 +
4271 +static int
4272 +getstring (idx, in, acc)
4273 +     int idx;
4274 +     sb *in;
4275 +     sb *acc;
4276 +{
4277 +  idx = sb_skip_white (idx, in);
4278 +
4279 +  while (idx < in->len
4280 +        && (in->ptr[idx] == '"'
4281 +            || in->ptr[idx] == '<'
4282 +            || (in->ptr[idx] == '\'' && alternate)))
4283 +    {
4284 +      if (in->ptr[idx] == '<')
4285 +       {
4286 +         if (alternate || mri)
4287 +           {
4288 +             int nest = 0;
4289 +             idx++;
4290 +             while ((in->ptr[idx] != '>' || nest)
4291 +                    && idx < in->len)
4292 +               {
4293 +                 if (in->ptr[idx] == '!')
4294 +                   {
4295 +                     idx++;
4296 +                     sb_add_char (acc, in->ptr[idx++]);
4297 +                   }
4298 +                 else
4299 +                   {
4300 +                     if (in->ptr[idx] == '>')
4301 +                       nest--;
4302 +                     if (in->ptr[idx] == '<')
4303 +                       nest++;
4304 +                     sb_add_char (acc, in->ptr[idx++]);
4305 +                   }
4306 +               }
4307 +             idx++;
4308 +           }
4309 +         else
4310 +           {
4311 +             int code;
4312 +             idx++;
4313 +             idx = exp_get_abs (_("Character code in string must be absolute expression.\n"),
4314 +                                idx, in, &code);
4315 +             sb_add_char (acc, code);
4316 +
4317 +             if (in->ptr[idx] != '>')
4318 +               ERROR ((stderr, _("Missing > for character code.\n")));
4319 +             idx++;
4320 +           }
4321 +       }
4322 +      else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
4323 +       {
4324 +         char tchar = in->ptr[idx];
4325 +         idx++;
4326 +         while (idx < in->len)
4327 +           {
4328 +             if (alternate && in->ptr[idx] == '!')
4329 +               {
4330 +                 idx++;
4331 +                 sb_add_char (acc, in->ptr[idx++]);
4332 +               }
4333 +             else
4334 +               {
4335 +                 if (in->ptr[idx] == tchar)
4336 +                   {
4337 +                     idx++;
4338 +                     if (idx >= in->len || in->ptr[idx] != tchar)
4339 +                       break;
4340 +                   }
4341 +                 sb_add_char (acc, in->ptr[idx]);
4342 +                 idx++;
4343 +               }
4344 +           }
4345 +       }
4346 +    }
4347 +
4348 +  return idx;
4349 +}
4350 +
4351 +/* .SDATA[C|Z] <string>  */
4352 +
4353 +static void
4354 +do_sdata (idx, in, type)
4355 +     int idx;
4356 +     sb *in;
4357 +     int type;
4358 +{
4359 +  int nc = 0;
4360 +  int pidx = -1;
4361 +  sb acc;
4362 +  sb_new (&acc);
4363 +  fprintf (outfile, ".byte\t");
4364 +
4365 +  while (!eol (idx, in))
4366 +    {
4367 +      int i;
4368 +      sb_reset (&acc);
4369 +      idx = sb_skip_white (idx, in);
4370 +      while (!eol (idx, in))
4371 +       {
4372 +         pidx = idx = get_any_string (idx, in, &acc, 0, 1);
4373 +         if (type == 'c')
4374 +           {
4375 +             if (acc.len > 255)
4376 +               {
4377 +                 ERROR ((stderr, _("string for SDATAC longer than 255 characters (%d).\n"), acc.len));
4378 +               }
4379 +             fprintf (outfile, "%d", acc.len);
4380 +             nc = 1;
4381 +           }
4382 +
4383 +         for (i = 0; i < acc.len; i++)
4384 +           {
4385 +             if (nc)
4386 +               {
4387 +                 fprintf (outfile, ",");
4388 +               }
4389 +             fprintf (outfile, "%d", acc.ptr[i]);
4390 +             nc = 1;
4391 +           }
4392 +
4393 +         if (type == 'z')
4394 +           {
4395 +             if (nc)
4396 +               fprintf (outfile, ",");
4397 +             fprintf (outfile, "0");
4398 +           }
4399 +         idx = sb_skip_comma (idx, in);
4400 +         if (idx == pidx)
4401 +           break;
4402 +       }
4403 +      if (!alternate && in->ptr[idx] != ',' && idx != in->len)
4404 +       {
4405 +         fprintf (outfile, "\n");
4406 +         ERROR ((stderr, _("illegal character in SDATA line (0x%x).\n"),
4407 +                 in->ptr[idx]));
4408 +         break;
4409 +       }
4410 +      idx++;
4411 +    }
4412 +  sb_kill (&acc);
4413 +  fprintf (outfile, "\n");
4414 +}
4415 +
4416 +/* .SDATAB <count> <string>  */
4417 +
4418 +static void
4419 +do_sdatab (idx, in)
4420 +     int idx;
4421 +     sb *in;
4422 +{
4423 +  int repeat;
4424 +  int i;
4425 +  sb acc;
4426 +  sb_new (&acc);
4427 +
4428 +  idx = exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx, in, &repeat);
4429 +  if (repeat <= 0)
4430 +    {
4431 +      ERROR ((stderr, _("Must have positive SDATAB repeat count (%d).\n"), repeat));
4432 +      repeat = 1;
4433 +    }
4434 +
4435 +  idx = sb_skip_comma (idx, in);
4436 +  idx = getstring (idx, in, &acc);
4437 +
4438 +  for (i = 0; i < repeat; i++)
4439 +    {
4440 +      if (i)
4441 +       fprintf (outfile, "\t");
4442 +      fprintf (outfile, ".byte\t");
4443 +      sb_print (outfile, &acc);
4444 +      fprintf (outfile, "\n");
4445 +    }
4446 +  sb_kill (&acc);
4447 +
4448 +}
4449 +
4450 +static int
4451 +new_file (name)
4452 +     const char *name;
4453 +{
4454 +  FILE *newone = fopen (name, "r");
4455 +  if (!newone)
4456 +    return 0;
4457 +
4458 +  if (isp == MAX_INCLUDES)
4459 +    FATAL ((stderr, _("Unreasonable include depth (%ld).\n"), (long) isp));
4460 +
4461 +  sp++;
4462 +  sp->handle = newone;
4463 +
4464 +  sb_new (&sp->name);
4465 +  sb_add_string (&sp->name, name);
4466 +
4467 +  sp->linecount = 1;
4468 +  sp->pushback_index = 0;
4469 +  sp->type = include_file;
4470 +  sp->index = 0;
4471 +  sb_new (&sp->pushback);
4472 +  return 1;
4473 +}
4474 +
4475 +static void
4476 +do_include (idx, in)
4477 +     int idx;
4478 +     sb *in;
4479 +{
4480 +  sb t;
4481 +  sb cat;
4482 +  include_path *includes;
4483 +
4484 +  sb_new (&t);
4485 +  sb_new (&cat);
4486 +
4487 +  if (! mri)
4488 +    idx = getstring (idx, in, &t);
4489 +  else
4490 +    {
4491 +      idx = sb_skip_white (idx, in);
4492 +      while (idx < in->len && ! ISWHITE (in->ptr[idx]))
4493 +       {
4494 +         sb_add_char (&t, in->ptr[idx]);
4495 +         ++idx;
4496 +       }
4497 +    }
4498 +
4499 +  for (includes = paths_head; includes; includes = includes->next)
4500 +    {
4501 +      sb_reset (&cat);
4502 +      sb_add_sb (&cat, &includes->path);
4503 +      sb_add_char (&cat, '/');
4504 +      sb_add_sb (&cat, &t);
4505 +      if (new_file (sb_name (&cat)))
4506 +       {
4507 +         break;
4508 +       }
4509 +    }
4510 +  if (!includes)
4511 +    {
4512 +      if (! new_file (sb_name (&t)))
4513 +       FATAL ((stderr, _("Can't open include file `%s'.\n"), sb_name (&t)));
4514 +    }
4515 +  sb_kill (&cat);
4516 +  sb_kill (&t);
4517 +}
4518 +
4519 +static void
4520 +include_pop ()
4521 +{
4522 +  if (sp != include_stack)
4523 +    {
4524 +      if (sp->handle)
4525 +       fclose (sp->handle);
4526 +      sp--;
4527 +    }
4528 +}
4529 +
4530 +/* Get the next character from the include stack.  If there's anything
4531 +   in the pushback buffer, take that first.  If we're at eof, pop from
4532 +   the stack and try again.  Keep the linecount up to date.  */
4533 +
4534 +static int
4535 +get ()
4536 +{
4537 +  int r;
4538 +
4539 +  if (sp->pushback.len != sp->pushback_index)
4540 +    {
4541 +      r = (char) (sp->pushback.ptr[sp->pushback_index++]);
4542 +      /* When they've all gone, reset the pointer.  */
4543 +      if (sp->pushback_index == sp->pushback.len)
4544 +       {
4545 +         sp->pushback.len = 0;
4546 +         sp->pushback_index = 0;
4547 +       }
4548 +    }
4549 +  else if (sp->handle)
4550 +    {
4551 +      r = getc (sp->handle);
4552 +    }
4553 +  else
4554 +    r = EOF;
4555 +
4556 +  if (r == EOF && isp)
4557 +    {
4558 +      include_pop ();
4559 +      r = get ();
4560 +      while (r == EOF && isp)
4561 +       {
4562 +         include_pop ();
4563 +         r = get ();
4564 +       }
4565 +      return r;
4566 +    }
4567 +  if (r == '\n')
4568 +    {
4569 +      sp->linecount++;
4570 +    }
4571 +
4572 +  return r;
4573 +}
4574 +
4575 +static int
4576 +linecount ()
4577 +{
4578 +  return sp->linecount;
4579 +}
4580 +
4581 +static int
4582 +include_next_index ()
4583 +{
4584 +  static int index;
4585 +  if (!unreasonable
4586 +      && index > MAX_REASONABLE)
4587 +    FATAL ((stderr, _("Unreasonable expansion (-u turns off check).\n")));
4588 +  return ++index;
4589 +}
4590 +
4591 +/* Initialize the chartype vector.  */
4592 +
4593 +static void
4594 +chartype_init ()
4595 +{
4596 +  int x;
4597 +  for (x = 0; x < 256; x++)
4598 +    {
4599 +      if (ISALPHA (x) || x == '_' || x == '$')
4600 +       chartype[x] |= FIRSTBIT;
4601 +
4602 +      if (mri && x == '.')
4603 +       chartype[x] |= FIRSTBIT;
4604 +
4605 +      if (ISDIGIT (x) || ISALPHA (x) || x == '_' || x == '$')
4606 +       chartype[x] |= NEXTBIT;
4607 +
4608 +      if (x == ' ' || x == '\t' || x == ',' || x == '"' || x == ';'
4609 +         || x == '"' || x == '<' || x == '>' || x == ')' || x == '(')
4610 +       chartype[x] |= SEPBIT;
4611 +
4612 +      if (x == 'b' || x == 'B'
4613 +         || x == 'q' || x == 'Q'
4614 +         || x == 'h' || x == 'H'
4615 +         || x == 'd' || x == 'D')
4616 +       chartype [x] |= BASEBIT;
4617 +
4618 +      if (x == ' ' || x == '\t')
4619 +       chartype[x] |= WHITEBIT;
4620 +
4621 +      if (x == comment_char)
4622 +       chartype[x] |= COMMENTBIT;
4623 +    }
4624 +}
4625 +
4626 +/* What to do with all the keywords.  */
4627 +#define PROCESS        0x1000  /* Run substitution over the line.  */
4628 +#define LAB            0x2000  /* Spit out the label.  */
4629 +
4630 +#define K_EQU          (PROCESS|1)
4631 +#define K_ASSIGN       (PROCESS|2)
4632 +#define K_REG          (PROCESS|3)
4633 +#define K_ORG          (PROCESS|4)
4634 +#define K_RADIX        (PROCESS|5)
4635 +#define K_DATA                 (LAB|PROCESS|6)
4636 +#define K_DATAB        (LAB|PROCESS|7)
4637 +#define K_SDATA        (LAB|PROCESS|8)
4638 +#define K_SDATAB       (LAB|PROCESS|9)
4639 +#define K_SDATAC       (LAB|PROCESS|10)
4640 +#define K_SDATAZ       (LAB|PROCESS|11)
4641 +#define K_RES          (LAB|PROCESS|12)
4642 +#define K_SRES                 (LAB|PROCESS|13)
4643 +#define K_SRESC        (LAB|PROCESS|14)
4644 +#define K_SRESZ        (LAB|PROCESS|15)
4645 +#define K_EXPORT       (LAB|PROCESS|16)
4646 +#define K_GLOBAL       (LAB|PROCESS|17)
4647 +#define K_PRINT        (LAB|PROCESS|19)
4648 +#define K_FORM                 (LAB|PROCESS|20)
4649 +#define K_HEADING      (LAB|PROCESS|21)
4650 +#define K_PAGE         (LAB|PROCESS|22)
4651 +#define K_IMPORT       (LAB|PROCESS|23)
4652 +#define K_PROGRAM      (LAB|PROCESS|24)
4653 +#define K_END          (PROCESS|25)
4654 +#define K_INCLUDE      (PROCESS|26)
4655 +#define K_IGNORED      (PROCESS|27)
4656 +#define K_ASSIGNA      (PROCESS|28)
4657 +#define K_ASSIGNC      (29)
4658 +#define K_AIF          (PROCESS|30)
4659 +#define K_AELSE                (PROCESS|31)
4660 +#define K_AENDI                (PROCESS|32)
4661 +#define K_AREPEAT      (PROCESS|33)
4662 +#define K_AENDR                (PROCESS|34)
4663 +#define K_AWHILE       (35)
4664 +#define K_AENDW                (PROCESS|36)
4665 +#define K_EXITM                (37)
4666 +#define K_MACRO                (PROCESS|38)
4667 +#define K_ENDM         (39)
4668 +#define K_ALIGN                (PROCESS|LAB|40)
4669 +#define K_ALTERNATE     (41)
4670 +#define K_DB           (LAB|PROCESS|42)
4671 +#define K_DW           (LAB|PROCESS|43)
4672 +#define K_DL           (LAB|PROCESS|44)
4673 +#define K_LOCAL                (45)
4674 +#define K_IFEQ         (PROCESS|46)
4675 +#define K_IFNE         (PROCESS|47)
4676 +#define K_IFLT         (PROCESS|48)
4677 +#define K_IFLE         (PROCESS|49)
4678 +#define K_IFGE         (PROCESS|50)
4679 +#define K_IFGT         (PROCESS|51)
4680 +#define K_IFC          (PROCESS|52)
4681 +#define K_IFNC         (PROCESS|53)
4682 +#define K_IRP          (PROCESS|54)
4683 +#define K_IRPC         (PROCESS|55)
4684 +
4685 +struct keyword {
4686 +  char *name;
4687 +  int code;
4688 +  int extra;
4689 +};
4690 +
4691 +static struct keyword kinfo[] = {
4692 +  { "EQU", K_EQU, 0 },
4693 +  { "ALTERNATE", K_ALTERNATE, 0 },
4694 +  { "ASSIGN", K_ASSIGN, 0 },
4695 +  { "REG", K_REG, 0 },
4696 +  { "ORG", K_ORG, 0 },
4697 +  { "RADIX", K_RADIX, 0 },
4698 +  { "DATA", K_DATA, 0 },
4699 +  { "DB", K_DB, 0 },
4700 +  { "DW", K_DW, 0 },
4701 +  { "DL", K_DL, 0 },
4702 +  { "DATAB", K_DATAB, 0 },
4703 +  { "SDATA", K_SDATA, 0 },
4704 +  { "SDATAB", K_SDATAB, 0 },
4705 +  { "SDATAZ", K_SDATAZ, 0 },
4706 +  { "SDATAC", K_SDATAC, 0 },
4707 +  { "RES", K_RES, 0 },
4708 +  { "SRES", K_SRES, 0 },
4709 +  { "SRESC", K_SRESC, 0 },
4710 +  { "SRESZ", K_SRESZ, 0 },
4711 +  { "EXPORT", K_EXPORT, 0 },
4712 +  { "GLOBAL", K_GLOBAL, 0 },
4713 +  { "PRINT", K_PRINT, 0 },
4714 +  { "FORM", K_FORM, 0 },
4715 +  { "HEADING", K_HEADING, 0 },
4716 +  { "PAGE", K_PAGE, 0 },
4717 +  { "PROGRAM", K_IGNORED, 0 },
4718 +  { "END", K_END, 0 },
4719 +  { "INCLUDE", K_INCLUDE, 0 },
4720 +  { "ASSIGNA", K_ASSIGNA, 0 },
4721 +  { "ASSIGNC", K_ASSIGNC, 0 },
4722 +  { "AIF", K_AIF, 0 },
4723 +  { "AELSE", K_AELSE, 0 },
4724 +  { "AENDI", K_AENDI, 0 },
4725 +  { "AREPEAT", K_AREPEAT, 0 },
4726 +  { "AENDR", K_AENDR, 0 },
4727 +  { "EXITM", K_EXITM, 0 },
4728 +  { "MACRO", K_MACRO, 0 },
4729 +  { "ENDM", K_ENDM, 0 },
4730 +  { "AWHILE", K_AWHILE, 0 },
4731 +  { "ALIGN", K_ALIGN, 0 },
4732 +  { "AENDW", K_AENDW, 0 },
4733 +  { "ALTERNATE", K_ALTERNATE, 0 },
4734 +  { "LOCAL", K_LOCAL, 0 },
4735 +  { NULL, 0, 0 }
4736 +};
4737 +
4738 +/* Although the conditional operators are handled by gas, we need to
4739 +   handle them here as well, in case they are used in a recursive
4740 +   macro to end the recursion.  */
4741 +
4742 +static struct keyword mrikinfo[] = {
4743 +  { "IFEQ", K_IFEQ, 0 },
4744 +  { "IFNE", K_IFNE, 0 },
4745 +  { "IFLT", K_IFLT, 0 },
4746 +  { "IFLE", K_IFLE, 0 },
4747 +  { "IFGE", K_IFGE, 0 },
4748 +  { "IFGT", K_IFGT, 0 },
4749 +  { "IFC", K_IFC, 0 },
4750 +  { "IFNC", K_IFNC, 0 },
4751 +  { "ELSEC", K_AELSE, 0 },
4752 +  { "ENDC", K_AENDI, 0 },
4753 +  { "MEXIT", K_EXITM, 0 },
4754 +  { "REPT", K_AREPEAT, 0 },
4755 +  { "IRP", K_IRP, 0 },
4756 +  { "IRPC", K_IRPC, 0 },
4757 +  { "ENDR", K_AENDR, 0 },
4758 +  { NULL, 0, 0 }
4759 +};
4760 +
4761 +/* Look for a pseudo op on the line. If one's there then call
4762 +   its handler.  */
4763 +
4764 +static int
4765 +process_pseudo_op (idx, line, acc)
4766 +     int idx;
4767 +     sb *line;
4768 +     sb *acc;
4769 +{
4770 +  int oidx = idx;
4771 +
4772 +  if (line->ptr[idx] == '.' || alternate || mri)
4773 +    {
4774 +      /* Scan forward and find pseudo name.  */
4775 +      char *in;
4776 +      hash_entry *ptr;
4777 +
4778 +      char *s;
4779 +      char *e;
4780 +      if (line->ptr[idx] == '.')
4781 +       idx++;
4782 +      in = line->ptr + idx;
4783 +      s = in;
4784 +      e = s;
4785 +      sb_reset (acc);
4786 +
4787 +      while (idx < line->len && *e && ISFIRSTCHAR (*e))
4788 +       {
4789 +         sb_add_char (acc, *e);
4790 +         e++;
4791 +         idx++;
4792 +       }
4793 +
4794 +      ptr = hash_lookup (&keyword_hash_table, acc);
4795 +
4796 +      if (!ptr)
4797 +       {
4798 +#if 0
4799 +         /* This one causes lots of pain when trying to preprocess
4800 +            ordinary code.  */
4801 +         WARNING ((stderr, _("Unrecognised pseudo op `%s'.\n"),
4802 +                   sb_name (acc)));
4803 +#endif
4804 +         return 0;
4805 +       }
4806 +      if (ptr->value.i & LAB)
4807 +       {
4808 +         /* Output the label.  */
4809 +         if (label.len)
4810 +           {
4811 +             fprintf (outfile, "%s:\t", sb_name (&label));
4812 +           }
4813 +         else
4814 +           fprintf (outfile, "\t");
4815 +       }
4816 +
4817 +      if (mri && ptr->value.i == K_END)
4818 +       {
4819 +         sb t;
4820 +
4821 +         sb_new (&t);
4822 +         sb_add_buffer (&t, line->ptr + oidx, idx - oidx);
4823 +         fprintf (outfile, "\t%s", sb_name (&t));
4824 +         sb_kill (&t);
4825 +       }
4826 +
4827 +      if (ptr->value.i & PROCESS)
4828 +       {
4829 +         /* Polish the rest of the line before handling the pseudo op.  */
4830 +#if 0
4831 +         strip_comments (line);
4832 +#endif
4833 +         sb_reset (acc);
4834 +         process_assigns (idx, line, acc);
4835 +         sb_reset (line);
4836 +         change_base (0, acc, line);
4837 +         idx = 0;
4838 +       }
4839 +      if (!condass_on ())
4840 +       {
4841 +         switch (ptr->value.i)
4842 +           {
4843 +           case K_AIF:
4844 +             do_aif (idx, line);
4845 +             break;
4846 +           case K_AELSE:
4847 +             do_aelse ();
4848 +             break;
4849 +           case K_AENDI:
4850 +             do_aendi ();
4851 +             break;
4852 +           }
4853 +         return 1;
4854 +       }
4855 +      else
4856 +       {
4857 +         switch (ptr->value.i)
4858 +           {
4859 +           case K_ALTERNATE:
4860 +             alternate = 1;
4861 +             macro_init (1, mri, 0, exp_get_abs);
4862 +             return 1;
4863 +           case K_AELSE:
4864 +             do_aelse ();
4865 +             return 1;
4866 +           case K_AENDI:
4867 +             do_aendi ();
4868 +             return 1;
4869 +           case K_ORG:
4870 +             ERROR ((stderr, _("ORG command not allowed.\n")));
4871 +             break;
4872 +           case K_RADIX:
4873 +             do_radix (line);
4874 +             return 1;
4875 +           case K_DB:
4876 +             do_data (idx, line, 1);
4877 +             return 1;
4878 +           case K_DW:
4879 +             do_data (idx, line, 2);
4880 +             return 1;
4881 +           case K_DL:
4882 +             do_data (idx, line, 4);
4883 +             return 1;
4884 +           case K_DATA:
4885 +             do_data (idx, line, 0);
4886 +             return 1;
4887 +           case K_DATAB:
4888 +             do_datab (idx, line);
4889 +             return 1;
4890 +           case K_SDATA:
4891 +             do_sdata (idx, line, 0);
4892 +             return 1;
4893 +           case K_SDATAB:
4894 +             do_sdatab (idx, line);
4895 +             return 1;
4896 +           case K_SDATAC:
4897 +             do_sdata (idx, line, 'c');
4898 +             return 1;
4899 +           case K_SDATAZ:
4900 +             do_sdata (idx, line, 'z');
4901 +             return 1;
4902 +           case K_ASSIGN:
4903 +             do_assign (0, 0, line);
4904 +             return 1;
4905 +           case K_AIF:
4906 +             do_aif (idx, line);
4907 +             return 1;
4908 +           case K_AREPEAT:
4909 +             do_arepeat (idx, line);
4910 +             return 1;
4911 +           case K_AENDW:
4912 +             do_aendw ();
4913 +             return 1;
4914 +           case K_AWHILE:
4915 +             do_awhile (idx, line);
4916 +             return 1;
4917 +           case K_AENDR:
4918 +             do_aendr ();
4919 +             return 1;
4920 +           case K_EQU:
4921 +             do_assign (1, idx, line);
4922 +             return 1;
4923 +           case K_ALIGN:
4924 +             do_align (idx, line);
4925 +             return 1;
4926 +           case K_RES:
4927 +             do_res (idx, line, 0);
4928 +             return 1;
4929 +           case K_SRES:
4930 +             do_res (idx, line, 's');
4931 +             return 1;
4932 +           case K_INCLUDE:
4933 +             do_include (idx, line);
4934 +             return 1;
4935 +           case K_LOCAL:
4936 +             do_local (idx, line);
4937 +             return 1;
4938 +           case K_MACRO:
4939 +             do_macro (idx, line);
4940 +             return 1;
4941 +           case K_ENDM:
4942 +             do_endm ();
4943 +             return 1;
4944 +           case K_SRESC:
4945 +             do_res (idx, line, 'c');
4946 +             return 1;
4947 +           case K_PRINT:
4948 +             do_print (idx, line);
4949 +             return 1;
4950 +           case K_FORM:
4951 +             do_form (idx, line);
4952 +             return 1;
4953 +           case K_HEADING:
4954 +             do_heading (idx, line);
4955 +             return 1;
4956 +           case K_PAGE:
4957 +             do_page ();
4958 +             return 1;
4959 +           case K_GLOBAL:
4960 +           case K_EXPORT:
4961 +             do_export (line);
4962 +             return 1;
4963 +           case K_IMPORT:
4964 +             return 1;
4965 +           case K_SRESZ:
4966 +             do_res (idx, line, 'z');
4967 +             return 1;
4968 +           case K_IGNORED:
4969 +             return 1;
4970 +           case K_END:
4971 +             do_end (line);
4972 +             return 1;
4973 +           case K_ASSIGNA:
4974 +             do_assigna (idx, line);
4975 +             return 1;
4976 +           case K_ASSIGNC:
4977 +             do_assignc (idx, line);
4978 +             return 1;
4979 +           case K_EXITM:
4980 +             do_exitm ();
4981 +             return 1;
4982 +           case K_REG:
4983 +             do_reg (idx, line);
4984 +             return 1;
4985 +           case K_IFEQ:
4986 +             do_if (idx, line, EQ);
4987 +             return 1;
4988 +           case K_IFNE:
4989 +             do_if (idx, line, NE);
4990 +             return 1;
4991 +           case K_IFLT:
4992 +             do_if (idx, line, LT);
4993 +             return 1;
4994 +           case K_IFLE:
4995 +             do_if (idx, line, LE);
4996 +             return 1;
4997 +           case K_IFGE:
4998 +             do_if (idx, line, GE);
4999 +             return 1;
5000 +           case K_IFGT:
5001 +             do_if (idx, line, GT);
5002 +             return 1;
5003 +           case K_IFC:
5004 +             do_ifc (idx, line, 0);
5005 +             return 1;
5006 +           case K_IFNC:
5007 +             do_ifc (idx, line, 1);
5008 +             return 1;
5009 +           case K_IRP:
5010 +             do_irp (idx, line, 0);
5011 +             return 1;
5012 +           case K_IRPC:
5013 +             do_irp (idx, line, 1);
5014 +             return 1;
5015 +           }
5016 +       }
5017 +    }
5018 +  return 0;
5019 +}
5020 +
5021 +/* Add a keyword to the hash table.  */
5022 +
5023 +static void
5024 +add_keyword (name, code)
5025 +     const char *name;
5026 +     int code;
5027 +{
5028 +  sb label;
5029 +  int j;
5030 +
5031 +  sb_new (&label);
5032 +  sb_add_string (&label, name);
5033 +
5034 +  hash_add_to_int_table (&keyword_hash_table, &label, code);
5035 +
5036 +  sb_reset (&label);
5037 +  for (j = 0; name[j]; j++)
5038 +    sb_add_char (&label, name[j] - 'A' + 'a');
5039 +  hash_add_to_int_table (&keyword_hash_table, &label, code);
5040 +
5041 +  sb_kill (&label);
5042 +}
5043 +
5044 +/* Build the keyword hash table - put each keyword in the table twice,
5045 +   once upper and once lower case.  */
5046 +
5047 +static void
5048 +process_init ()
5049 +{
5050 +  int i;
5051 +
5052 +  for (i = 0; kinfo[i].name; i++)
5053 +    add_keyword (kinfo[i].name, kinfo[i].code);
5054 +
5055 +  if (mri)
5056 +    {
5057 +      for (i = 0; mrikinfo[i].name; i++)
5058 +       add_keyword (mrikinfo[i].name, mrikinfo[i].code);
5059 +    }
5060 +}
5061 +
5062 +static void
5063 +do_define (string)
5064 +     const char *string;
5065 +{
5066 +  sb label;
5067 +  int res = 1;
5068 +  hash_entry *ptr;
5069 +  sb_new (&label);
5070 +
5071 +  while (*string)
5072 +    {
5073 +      if (*string == '=')
5074 +       {
5075 +         sb value;
5076 +         sb_new (&value);
5077 +         string++;
5078 +         while (*string)
5079 +           {
5080 +             sb_add_char (&value, *string);
5081 +             string++;
5082 +           }
5083 +         exp_get_abs (_("Invalid expression on command line.\n"),
5084 +                      0, &value, &res);
5085 +         sb_kill (&value);
5086 +         break;
5087 +       }
5088 +      sb_add_char (&label, *string);
5089 +
5090 +      string++;
5091 +    }
5092 +
5093 +  ptr = hash_create (&vars, &label);
5094 +  free_old_entry (ptr);
5095 +  ptr->type = hash_integer;
5096 +  ptr->value.i = res;
5097 +  sb_kill (&label);
5098 +}
5099 +
5100 +char *program_name;
5101 +
5102 +/* The list of long options.  */
5103 +static struct option long_options[] =
5104 +{
5105 +  { "alternate", no_argument, 0, 'a' },
5106 +  { "include", required_argument, 0, 'I' },
5107 +  { "commentchar", required_argument, 0, 'c' },
5108 +  { "copysource", no_argument, 0, 's' },
5109 +  { "debug", no_argument, 0, 'd' },
5110 +  { "help", no_argument, 0, 'h' },
5111 +  { "mri", no_argument, 0, 'M' },
5112 +  { "output", required_argument, 0, 'o' },
5113 +  { "print", no_argument, 0, 'p' },
5114 +  { "unreasonable", no_argument, 0, 'u' },
5115 +  { "version", no_argument, 0, 'v' },
5116 +  { "define", required_argument, 0, 'd' },
5117 +  { NULL, no_argument, 0, 0 }
5118 +};
5119 +
5120 +/* Show a usage message and exit.  */
5121 +static void
5122 +show_usage (file, status)
5123 +     FILE *file;
5124 +     int status;
5125 +{
5126 +  fprintf (file, _("\
5127 +Usage: %s \n\
5128 +  [-a]      [--alternate]         enter alternate macro mode\n\
5129 +  [-c char] [--commentchar char]  change the comment character from !\n\
5130 +  [-d]      [--debug]             print some debugging info\n\
5131 +  [-h]      [--help]              print this message\n\
5132 +  [-M]      [--mri]               enter MRI compatibility mode\n\
5133 +  [-o out]  [--output out]        set the output file\n\
5134 +  [-p]      [--print]             print line numbers\n"), program_name);
5135 +  fprintf (file, _("\
5136 +  [-s]      [--copysource]        copy source through as comments \n\
5137 +  [-u]      [--unreasonable]      allow unreasonable nesting\n\
5138 +  [-v]      [--version]           print the program version\n\
5139 +  [-Dname=value]                  create preprocessor variable called name, with value\n\
5140 +  [-Ipath]                        add to include path list\n\
5141 +  [in-file]\n"));
5142 +  if (status == 0)
5143 +    printf (_("Report bugs to %s\n"), REPORT_BUGS_TO);
5144 +  exit (status);
5145 +}
5146 +
5147 +/* Display a help message and exit.  */
5148 +
5149 +static void
5150 +show_help ()
5151 +{
5152 +  printf (_("%s: Gnu Assembler Macro Preprocessor\n"), program_name);
5153 +  show_usage (stdout, 0);
5154 +}
5155 +
5156 +int main PARAMS ((int, char **));
5157 +
5158 +int
5159 +main (argc, argv)
5160 +     int argc;
5161 +     char **argv;
5162 +{
5163 +  int opt;
5164 +  char *out_name = 0;
5165 +  sp = include_stack;
5166 +
5167 +  ifstack[0].on = 1;
5168 +  ifi = 0;
5169 +
5170 +#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
5171 +  setlocale (LC_MESSAGES, "");
5172 +#endif
5173 +#if defined (HAVE_SETLOCALE)
5174 +  setlocale (LC_CTYPE, "");
5175 +#endif
5176 +  bindtextdomain (PACKAGE, LOCALEDIR);
5177 +  textdomain (PACKAGE);
5178 +
5179 +  program_name = argv[0];
5180 +  xmalloc_set_program_name (program_name);
5181 +
5182 +  hash_new_table (101, &keyword_hash_table);
5183 +  hash_new_table (101, &assign_hash_table);
5184 +  hash_new_table (101, &vars);
5185 +
5186 +  sb_new (&label);
5187 +
5188 +  while ((opt = getopt_long (argc, argv, "I:sdhavc:upo:D:M", long_options,
5189 +                            (int *) NULL))
5190 +        != EOF)
5191 +    {
5192 +      switch (opt)
5193 +       {
5194 +       case 'o':
5195 +         out_name = optarg;
5196 +         break;
5197 +       case 'u':
5198 +         unreasonable = 1;
5199 +         break;
5200 +       case 'I':
5201 +         {
5202 +           include_path *p = (include_path *) xmalloc (sizeof (include_path));
5203 +           p->next = NULL;
5204 +           sb_new (&p->path);
5205 +           sb_add_string (&p->path, optarg);
5206 +           if (paths_tail)
5207 +             paths_tail->next = p;
5208 +           else
5209 +             paths_head = p;
5210 +           paths_tail = p;
5211 +         }
5212 +         break;
5213 +       case 'p':
5214 +         print_line_number = 1;
5215 +         break;
5216 +       case 'c':
5217 +         comment_char = optarg[0];
5218 +         break;
5219 +       case 'a':
5220 +         alternate = 1;
5221 +         break;
5222 +       case 's':
5223 +         copysource = 1;
5224 +         break;
5225 +       case 'd':
5226 +         stats = 1;
5227 +         break;
5228 +       case 'D':
5229 +         do_define (optarg);
5230 +         break;
5231 +       case 'M':
5232 +         mri = 1;
5233 +         comment_char = ';';
5234 +         break;
5235 +       case 'h':
5236 +         show_help ();
5237 +         /* NOTREACHED  */
5238 +       case 'v':
5239 +         /* This output is intended to follow the GNU standards document.  */
5240 +         printf (_("GNU assembler pre-processor %s\n"), program_version);
5241 +         printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
5242 +         printf (_("\
5243 +This program is free software; you may redistribute it under the terms of\n\
5244 +the GNU General Public License.  This program has absolutely no warranty.\n"));
5245 +         exit (0);
5246 +         /* NOTREACHED  */
5247 +       case 0:
5248 +         break;
5249 +       default:
5250 +         show_usage (stderr, 1);
5251 +         /* NOTREACHED  */
5252 +       }
5253 +    }
5254 +
5255 +  process_init ();
5256 +
5257 +  macro_init (alternate, mri, 0, exp_get_abs);
5258 +
5259 +  if (out_name)
5260 +    {
5261 +      outfile = fopen (out_name, "w");
5262 +      if (!outfile)
5263 +       {
5264 +         fprintf (stderr, _("%s: Can't open output file `%s'.\n"),
5265 +                  program_name, out_name);
5266 +         exit (1);
5267 +       }
5268 +    }
5269 +  else
5270 +    {
5271 +      outfile = stdout;
5272 +    }
5273 +
5274 +  chartype_init ();
5275 +  if (!outfile)
5276 +    outfile = stdout;
5277 +
5278 +  /* Process all the input files.  */
5279 +
5280 +  while (optind < argc)
5281 +    {
5282 +      if (new_file (argv[optind]))
5283 +       {
5284 +         process_file ();
5285 +       }
5286 +      else
5287 +       {
5288 +         fprintf (stderr, _("%s: Can't open input file `%s'.\n"),
5289 +                  program_name, argv[optind]);
5290 +         exit (1);
5291 +       }
5292 +      optind++;
5293 +    }
5294 +
5295 +  quit ();
5296 +  return 0;
5297 +}
5298 +
5299 +/* This function is used because an abort in some of the other files
5300 +   may be compiled into as_abort because they include as.h.  */
5301 +
5302 +void
5303 +as_abort (file, line, fn)
5304 +     const char *file, *fn;
5305 +     int line;
5306 +{
5307 +  fprintf (stderr, _("Internal error, aborting at %s line %d"), file, line);
5308 +  if (fn)
5309 +    fprintf (stderr, " in %s", fn);
5310 +  fprintf (stderr, _("\nPlease report this bug.\n"));
5311 +  exit (1);
5312 +}
5313 +
5314 +/* duplicated from as internals */
5315 +
5316 +static void
5317 +identify (char *file)
5318 +{
5319 +  static int identified;
5320 +
5321 +  if (identified)
5322 +    return;
5323 +  identified++;
5324 +
5325 +  if (file)
5326 +    fprintf (stderr, "%s: ", file);
5327 +  fprintf (stderr, _("Assembler messages:\n"));
5328 +}
5329 +
5330 +/* The number of warnings issued.  */
5331 +static int warning_count;
5332 +
5333 +/* The common portion of as_warn and as_warn_where.  */
5334 +
5335 +static void
5336 +as_warn_internal (char *file, unsigned int line, char *buffer)
5337 +{
5338 +  ++warning_count;
5339 +
5340 +  identify (file);
5341 +  if (file)
5342 +    fprintf (stderr, "%s:%u: ", file, line);
5343 +  fprintf (stderr, _("Warning: "));
5344 +  fputs (buffer, stderr);
5345 +  (void) putc ('\n', stderr);
5346 +}
5347 +
5348 +/* Send to stderr a string as a warning, and locate warning
5349 +   in input file(s).
5350 +   Please only use this for when we have some recovery action.
5351 +   Please explain in string (which may have '\n's) what recovery was
5352 +   done.  */
5353 +
5354 +void
5355 +as_warn (const char *format, ...)
5356 +{
5357 +  va_list args;
5358 +  char buffer[2000];
5359 +
5360 +  if (1 /*!flag_no_warnings*/)
5361 +    {
5362 +      va_start (args, format);
5363 +      vsprintf (buffer, format, args);
5364 +      va_end (args);
5365 +      as_warn_internal ((char *) NULL, 0, buffer);
5366 +    }
5367 +}
5368 +
5369 +/* Like as_bad but the file name and line number are passed in.
5370 +   Unfortunately, we have to repeat the function in order to handle
5371 +   the varargs correctly and portably.  */
5372 +
5373 +void
5374 +as_warn_where (char *file, unsigned int line, const char *format, ...)
5375 +{
5376 +  va_list args;
5377 +  char buffer[2000];
5378 +
5379 +  if (1 /*!flag_no_warnings*/)
5380 +    {
5381 +      va_start (args, format);
5382 +      vsprintf (buffer, format, args);
5383 +      va_end (args);
5384 +      as_warn_internal (file, line, buffer);
5385 +    }
5386 +}
5387 +
5388 +/* Nonzero if we've hit a 'bad error', and should not write an obj file,
5389 +   and exit with a nonzero error code.  */
5390 +
5391 +static int error_count;
5392 +
5393 +/* The common portion of as_bad and as_bad_where.  */
5394 +
5395 +static void
5396 +as_bad_internal (char *file, unsigned int line, char *buffer)
5397 +{
5398 +  ++error_count;
5399 +
5400 +  identify (file);
5401 +  if (file)
5402 +    fprintf (stderr, "%s:%u: ", file, line);
5403 +  fprintf (stderr, _("Error: "));
5404 +  fputs (buffer, stderr);
5405 +  (void) putc ('\n', stderr);
5406 +}
5407 +
5408 +/* Send to stderr a string as a warning, and locate warning in input
5409 +   file(s).  Please us when there is no recovery, but we want to
5410 +   continue processing but not produce an object file.
5411 +   Please explain in string (which may have '\n's) what recovery was
5412 +   done.  */
5413 +
5414 +void
5415 +as_bad (const char *format, ...)
5416 +{
5417 +  va_list args;
5418 +  char buffer[2000];
5419 +
5420 +  va_start (args, format);
5421 +  vsprintf (buffer, format, args);
5422 +  va_end (args);
5423 +
5424 +  as_bad_internal ((char *) NULL, 0, buffer);
5425 +}
5426 +
5427 +/* Like as_bad but the file name and line number are passed in.
5428 +   Unfortunately, we have to repeat the function in order to handle
5429 +   the varargs correctly and portably.  */
5430 +
5431 +void
5432 +as_bad_where (char *file, unsigned int line, const char *format, ...)
5433 +{
5434 +  va_list args;
5435 +  char buffer[2000];
5436 +
5437 +  va_start (args, format);
5438 +  vsprintf (buffer, format, args);
5439 +  va_end (args);
5440 +
5441 +  as_bad_internal (file, line, buffer);
5442 +}
5443 +
5444 +#ifndef LEX_AT
5445 +/* The m88k unfortunately uses @ as a label beginner.  */
5446 +#define LEX_AT 0
5447 +#endif
5448 +
5449 +#ifndef LEX_BR
5450 +/* The RS/6000 assembler uses {,},[,] as parts of symbol names.  */
5451 +#define LEX_BR 0
5452 +#endif
5453 +
5454 +#ifndef LEX_PCT
5455 +/* The Delta 68k assembler permits % inside label names.  */
5456 +#define LEX_PCT 0
5457 +#endif
5458 +
5459 +#ifndef LEX_QM
5460 +/* The PowerPC Windows NT assemblers permits ? inside label names.  */
5461 +#define LEX_QM 0
5462 +#endif
5463 +
5464 +#ifndef LEX_HASH
5465 +/* The IA-64 assembler uses # as a suffix designating a symbol.  We include
5466 +   it in the symbol and strip it out in tc_canonicalize_symbol_name.  */
5467 +#define LEX_HASH 0
5468 +#endif
5469 +
5470 +#ifndef LEX_DOLLAR
5471 +/* The a29k assembler does not permits labels to start with $.  */
5472 +#define LEX_DOLLAR 3
5473 +#endif
5474 +
5475 +#ifndef LEX_TILDE
5476 +/* The Delta 68k assembler permits ~ at start of label names.  */
5477 +#define LEX_TILDE 0
5478 +#endif
5479 +
5480 +/* Used by is_... macros. our ctype[].  */
5481 +char lex_type[256] = {
5482 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* @ABCDEFGHIJKLMNO */
5483 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* PQRSTUVWXYZ[\]^_ */
5484 +  0, 0, 0, LEX_HASH, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
5485 +  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */
5486 +  LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
5487 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */
5488 +  0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,      /* `abcdefghijklmno */
5489 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, LEX_TILDE, 0, /* pqrstuvwxyz{|}~.  */
5490 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5491 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5492 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5493 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5494 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5495 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5496 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5497 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
5498 +};
5499 +
5500 +/* just a stub to satisfy unused function in sb.o */
5501 +int do_scrub_chars (int (*get) (char*, int), char *tostart, int tolen) {}
5502 diff -urNbB binutils-2.16.91.0.2.org/gas/macro.c binutils-2.16.91.0.2/gas/macro.c
5503 --- binutils-2.16.91.0.2.org/gas/macro.c        2005-05-10 22:46:44.000000000 +0000
5504 +++ binutils-2.16.91.0.2/gas/macro.c    2005-07-21 18:31:04.000000000 +0000
5505 @@ -77,8 +77,8 @@
5506  static int get_apost_token (int, sb *, sb *, int);
5507  static int sub_actual (int, sb *, sb *, struct hash_control *, int, sb *, int);
5508  static const char *macro_expand_body
5509 -  (sb *, sb *, formal_entry *, struct hash_control *, const macro_entry *);
5510 -static const char *macro_expand (int, sb *, macro_entry *, sb *);
5511 +  (sb *, sb *, formal_entry *, struct hash_control *, const macro_entry *, int);
5512 +static const char *macro_expand (int, sb *, macro_entry *, sb *, int);
5513  static void free_macro(macro_entry *);
5514  
5515  #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
5516 @@ -762,7 +762,7 @@
5517  
5518  static const char *
5519  macro_expand_body (sb *in, sb *out, formal_entry *formals,
5520 -                  struct hash_control *formal_hash, const macro_entry *macro)
5521 +                  struct hash_control *formal_hash, const macro_entry *macro, int comment_char)
5522  {
5523    sb t;
5524    int src = 0, inquote = 0, macro_line = 0;
5525 @@ -794,7 +794,14 @@
5526        else if (in->ptr[src] == '\\')
5527         {
5528           src++;
5529 -         if (src < in->len && in->ptr[src] == '(')
5530 +         if (in->ptr[src] == comment_char && comment_char != '\0')
5531 +           {
5532 +             /* This is a comment, just drop the rest of the line.  */
5533 +             while (src < in->len
5534 +                    && in->ptr[src] != '\n')
5535 +               src++;
5536 +           }
5537 +         else if (src < in->len && in->ptr[src] == '(')
5538             {
5539               /* Sub in till the next ')' literally.  */
5540               src++;
5541 @@ -875,7 +882,7 @@
5542           else
5543             {
5544               src = sb_skip_white (src + 5, in);
5545 -             while (in->ptr[src] != '\n')
5546 +             while (in->ptr[src] != '\n' && in->ptr[src] != comment_char)
5547                 {
5548                   const char *name;
5549                   formal_entry *f = new_formal ();
5550 @@ -911,6 +918,17 @@
5551                 }
5552             }
5553         }
5554 +      else if (comment_char != '\0'
5555 +              && in->ptr[src] == comment_char
5556 +              && src + 1 < in->len
5557 +              && in->ptr[src + 1] == comment_char
5558 +              && !inquote)
5559 +       {
5560 +         /* Two comment chars in a row cause the rest of the line to
5561 +            be dropped.  */
5562 +         while (src < in->len && in->ptr[src] != '\n')
5563 +           src++;
5564 +       }
5565        else if (in->ptr[src] == '"'
5566                || (macro_mri && in->ptr[src] == '\''))
5567         {
5568 @@ -992,7 +1010,7 @@
5569     body.  */
5570  
5571  static const char *
5572 -macro_expand (int idx, sb *in, macro_entry *m, sb *out)
5573 +macro_expand (int idx, sb *in, macro_entry *m, sb *out, int comment_char)
5574  {
5575    sb t;
5576    formal_entry *ptr;
5577 @@ -1038,7 +1056,7 @@
5578  
5579    /* Peel off the actuals and store them away in the hash tables' actuals.  */
5580    idx = sb_skip_white (idx, in);
5581 -  while (idx < in->len)
5582 +  while (idx < in->len && in->ptr[idx] != comment_char)
5583      {
5584        int scan;
5585  
5586 @@ -1167,7 +1185,7 @@
5587           sb_add_string (&ptr->actual, buffer);
5588         }
5589  
5590 -      err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m);
5591 +      err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m, comment_char);
5592      }
5593  
5594    /* Discard any unnamed formal arguments.  */
5595 @@ -1200,7 +1218,7 @@
5596     *EXPAND.  Return 1 if a macro is found, 0 otherwise.  */
5597  
5598  int
5599 -check_macro (const char *line, sb *expand,
5600 +check_macro (const char *line, sb *expand, int comment_char,
5601              const char **error, macro_entry **info)
5602  {
5603    const char *s;
5604 @@ -1235,7 +1253,7 @@
5605      sb_add_char (&line_sb, *s++);
5606  
5607    sb_new (expand);
5608 -  *error = macro_expand (0, &line_sb, macro, expand);
5609 +  *error = macro_expand (0, &line_sb, macro, expand, comment_char);
5610  
5611    sb_kill (&line_sb);
5612  
5613 @@ -1296,7 +1314,7 @@
5614     success, or an error message otherwise.  */
5615  
5616  const char *
5617 -expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
5618 +expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *), int comment_char)
5619  {
5620    sb sub;
5621    formal_entry f;
5622 @@ -1329,16 +1347,16 @@
5623    sb_reset (out);
5624  
5625    idx = sb_skip_comma (idx, in);
5626 -  if (idx >= in->len)
5627 +  if (idx >= in->len || in->ptr[idx] == comment_char)
5628      {
5629        /* Expand once with a null string.  */
5630 -      err = macro_expand_body (&sub, out, &f, h, 0);
5631 +      err = macro_expand_body (&sub, out, &f, h, 0, comment_char);
5632      }
5633    else
5634      {
5635        if (irpc && in->ptr[idx] == '"')
5636         ++idx;
5637 -      while (idx < in->len)
5638 +      while (idx < in->len && in->ptr[idx] != comment_char)
5639         {
5640           if (!irpc)
5641             idx = get_any_string (idx, in, &f.actual);
5642 @@ -1349,7 +1367,7 @@
5643                   int nxt;
5644  
5645                   nxt = sb_skip_white (idx + 1, in);
5646 -                 if (nxt >= in->len)
5647 +                 if (nxt >= in->len || in->ptr[nxt] == comment_char)
5648                     {
5649                       idx = nxt;
5650                       break;
5651 @@ -1359,7 +1377,7 @@
5652               sb_add_char (&f.actual, in->ptr[idx]);
5653               ++idx;
5654             }
5655 -         err = macro_expand_body (&sub, out, &f, h, 0);
5656 +         err = macro_expand_body (&sub, out, &f, h, 0, comment_char);
5657           if (err != NULL)
5658             break;
5659           if (!irpc)
5660 diff -urNbB binutils-2.16.91.0.2.org/gas/macro.h binutils-2.16.91.0.2/gas/macro.h
5661 --- binutils-2.16.91.0.2.org/gas/macro.h        2005-05-10 22:46:44.000000000 +0000
5662 +++ binutils-2.16.91.0.2/gas/macro.h    2005-07-21 18:31:04.000000000 +0000
5663 @@ -90,8 +90,8 @@
5664  extern void macro_mri_mode (int);
5665  extern const char *define_macro
5666    (int, sb *, sb *, int (*) (sb *), char *, unsigned int, const char **);
5667 -extern int check_macro (const char *, sb *, const char **, macro_entry **);
5668 +extern int check_macro (const char *, sb *, int, const char **, macro_entry **);
5669  extern void delete_macro (const char *);
5670 -extern const char *expand_irp (int, int, sb *, sb *, int (*) (sb *));
5671 +extern const char *expand_irp (int, int, sb *, sb *, int (*) (sb *), int);
5672  
5673  #endif
5674 diff -urNbB binutils-2.16.91.0.2.org/gas/macro.h.orig binutils-2.16.91.0.2/gas/macro.h.orig
5675 --- binutils-2.16.91.0.2.org/gas/macro.h.orig   1970-01-01 00:00:00.000000000 +0000
5676 +++ binutils-2.16.91.0.2/gas/macro.h.orig       2005-05-10 22:46:44.000000000 +0000
5677 @@ -0,0 +1,97 @@
5678 +/* macro.h - header file for macro support for gas
5679 +   Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004
5680 +   Free Software Foundation, Inc.
5681 +
5682 +   Written by Steve and Judy Chamberlain of Cygnus Support,
5683 +      sac@cygnus.com
5684 +
5685 +   This file is part of GAS, the GNU Assembler.
5686 +
5687 +   GAS is free software; you can redistribute it and/or modify
5688 +   it under the terms of the GNU General Public License as published by
5689 +   the Free Software Foundation; either version 2, or (at your option)
5690 +   any later version.
5691 +
5692 +   GAS is distributed in the hope that it will be useful,
5693 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
5694 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5695 +   GNU General Public License for more details.
5696 +
5697 +   You should have received a copy of the GNU General Public License
5698 +   along with GAS; see the file COPYING.  If not, write to the Free
5699 +   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
5700 +   02110-1301, USA.  */
5701 +
5702 +#ifndef MACRO_H
5703 +
5704 +#define MACRO_H
5705 +
5706 +#include "ansidecl.h"
5707 +#include "sb.h"
5708 +
5709 +/* Structures used to store macros.
5710 +
5711 +   Each macro knows its name and included text.  It gets built with a
5712 +   list of formal arguments, and also keeps a hash table which points
5713 +   into the list to speed up formal search.  Each formal knows its
5714 +   name and its default value.  Each time the macro is expanded, the
5715 +   formals get the actual values attached to them.  */
5716 +
5717 +/* Describe the formal arguments to a macro.  */
5718 +
5719 +typedef struct formal_struct {
5720 +  struct formal_struct *next;  /* Next formal in list.  */
5721 +  sb name;                     /* Name of the formal.  */
5722 +  sb def;                      /* The default value.  */
5723 +  sb actual;                   /* The actual argument (changed on each expansion).  */
5724 +  int index;                   /* The index of the formal 0..formal_count - 1.  */
5725 +  enum formal_type
5726 +    {
5727 +      FORMAL_OPTIONAL,
5728 +      FORMAL_REQUIRED,
5729 +      FORMAL_VARARG
5730 +    } type;                    /* The kind of the formal.  */
5731 +} formal_entry;
5732 +
5733 +/* Other values found in the index field of a formal_entry.  */
5734 +#define QUAL_INDEX (-1)
5735 +#define NARG_INDEX (-2)
5736 +#define LOCAL_INDEX (-3)
5737 +
5738 +/* Describe the macro.  */
5739 +
5740 +typedef struct macro_struct
5741 +{
5742 +  sb sub;                              /* Substitution text.  */
5743 +  int formal_count;                    /* Number of formal args.  */
5744 +  formal_entry *formals;               /* Pointer to list of formal_structs.  */
5745 +  struct hash_control *formal_hash;    /* Hash table of formals.  */
5746 +  const char *name;                    /* Macro name.  */
5747 +  char *file;                          /* File the macro was defined in.  */
5748 +  unsigned int line;                   /* Line number of definition.  */
5749 +} macro_entry;
5750 +
5751 +/* Whether any macros have been defined.  */
5752 +
5753 +extern int macro_defined;
5754 +
5755 +/* The macro nesting level.  */
5756 +
5757 +extern int macro_nest;
5758 +
5759 +/* The macro hash table.  */
5760 +
5761 +extern struct hash_control *macro_hash;
5762 +
5763 +extern int buffer_and_nest (const char *, const char *, sb *, int (*) (sb *));
5764 +extern void macro_init
5765 +  (int, int, int, int (*) (const char *, int, sb *, int *));
5766 +extern void macro_set_alternate (int);
5767 +extern void macro_mri_mode (int);
5768 +extern const char *define_macro
5769 +  (int, sb *, sb *, int (*) (sb *), char *, unsigned int, const char **);
5770 +extern int check_macro (const char *, sb *, const char **, macro_entry **);
5771 +extern void delete_macro (const char *);
5772 +extern const char *expand_irp (int, int, sb *, sb *, int (*) (sb *));
5773 +
5774 +#endif
5775 diff -urNbB binutils-2.16.91.0.2.org/gas/read.c binutils-2.16.91.0.2/gas/read.c
5776 --- binutils-2.16.91.0.2.org/gas/read.c 2005-06-22 20:53:34.000000000 +0000
5777 +++ binutils-2.16.91.0.2/gas/read.c     2005-07-21 18:31:04.000000000 +0000
5778 @@ -555,7 +555,7 @@
5779    const char *err;
5780    macro_entry *macro;
5781  
5782 -  if (check_macro (line, &out, &err, &macro))
5783 +  if (check_macro (line, &out, '\0', &err, &macro))
5784      {
5785        if (err != NULL)
5786         as_bad ("%s", err);
5787 @@ -1958,7 +1958,7 @@
5788  
5789    sb_new (&out);
5790  
5791 -  err = expand_irp (irpc, 0, &s, &out, get_line_sb);
5792 +  err = expand_irp (irpc, 0, &s, &out, get_line_sb, '\0');
5793    if (err != NULL)
5794      as_bad_where (file, line, "%s", err);
5795  
5796 diff -urNbB binutils-2.16.91.0.2.org/gas/read.c.orig binutils-2.16.91.0.2/gas/read.c.orig
5797 --- binutils-2.16.91.0.2.org/gas/read.c.orig    1970-01-01 00:00:00.000000000 +0000
5798 +++ binutils-2.16.91.0.2/gas/read.c.orig        2005-06-22 20:53:34.000000000 +0000
5799 @@ -0,0 +1,5322 @@
5800 +/* read.c - read a source file -
5801 +   Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
5802 +   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
5803 +   Free Software Foundation, Inc.
5804 +
5805 +This file is part of GAS, the GNU Assembler.
5806 +
5807 +GAS is free software; you can redistribute it and/or modify
5808 +it under the terms of the GNU General Public License as published by
5809 +the Free Software Foundation; either version 2, or (at your option)
5810 +any later version.
5811 +
5812 +GAS is distributed in the hope that it will be useful,
5813 +but WITHOUT ANY WARRANTY; without even the implied warranty of
5814 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5815 +GNU General Public License for more details.
5816 +
5817 +You should have received a copy of the GNU General Public License
5818 +along with GAS; see the file COPYING.  If not, write to the Free
5819 +Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
5820 +02110-1301, USA.  */
5821 +
5822 +/* If your chars aren't 8 bits, you will change this a bit (eg. to 0xFF).
5823 +   But then, GNU isn't spozed to run on your machine anyway.
5824 +   (RMS is so shortsighted sometimes.)  */
5825 +#define MASK_CHAR ((int)(unsigned char) -1)
5826 +
5827 +/* This is the largest known floating point format (for now). It will
5828 +   grow when we do 4361 style flonums.  */
5829 +#define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
5830 +
5831 +/* Routines that read assembler source text to build spaghetti in memory.
5832 +   Another group of these functions is in the expr.c module.  */
5833 +
5834 +#include "as.h"
5835 +#include "safe-ctype.h"
5836 +#include "subsegs.h"
5837 +#include "sb.h"
5838 +#include "macro.h"
5839 +#include "obstack.h"
5840 +#include "listing.h"
5841 +#include "ecoff.h"
5842 +#include "dw2gencfi.h"
5843 +
5844 +#ifndef TC_START_LABEL
5845 +#define TC_START_LABEL(x,y) (x == ':')
5846 +#endif
5847 +
5848 +/* Set by the object-format or the target.  */
5849 +#ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
5850 +#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR)               \
5851 +  do                                                           \
5852 +    {                                                          \
5853 +      if ((SIZE) >= 8)                                         \
5854 +       (P2VAR) = 3;                                            \
5855 +      else if ((SIZE) >= 4)                                    \
5856 +       (P2VAR) = 2;                                            \
5857 +      else if ((SIZE) >= 2)                                    \
5858 +       (P2VAR) = 1;                                            \
5859 +      else                                                     \
5860 +       (P2VAR) = 0;                                            \
5861 +    }                                                          \
5862 +  while (0)
5863 +#endif
5864 +
5865 +char *input_line_pointer;      /*->next char of source file to parse.  */
5866 +
5867 +#if BITS_PER_CHAR != 8
5868 +/*  The following table is indexed by[(char)] and will break if
5869 +    a char does not have exactly 256 states (hopefully 0:255!)!  */
5870 +die horribly;
5871 +#endif
5872 +
5873 +#ifndef LEX_AT
5874 +/* The m88k unfortunately uses @ as a label beginner.  */
5875 +#define LEX_AT 0
5876 +#endif
5877 +
5878 +#ifndef LEX_BR
5879 +/* The RS/6000 assembler uses {,},[,] as parts of symbol names.  */
5880 +#define LEX_BR 0
5881 +#endif
5882 +
5883 +#ifndef LEX_PCT
5884 +/* The Delta 68k assembler permits % inside label names.  */
5885 +#define LEX_PCT 0
5886 +#endif
5887 +
5888 +#ifndef LEX_QM
5889 +/* The PowerPC Windows NT assemblers permits ? inside label names.  */
5890 +#define LEX_QM 0
5891 +#endif
5892 +
5893 +#ifndef LEX_HASH
5894 +/* The IA-64 assembler uses # as a suffix designating a symbol.  We include
5895 +   it in the symbol and strip it out in tc_canonicalize_symbol_name.  */
5896 +#define LEX_HASH 0
5897 +#endif
5898 +
5899 +#ifndef LEX_DOLLAR
5900 +/* The a29k assembler does not permits labels to start with $.  */
5901 +#define LEX_DOLLAR 3
5902 +#endif
5903 +
5904 +#ifndef LEX_TILDE
5905 +/* The Delta 68k assembler permits ~ at start of label names.  */
5906 +#define LEX_TILDE 0
5907 +#endif
5908 +
5909 +/* Used by is_... macros. our ctype[].  */
5910 +char lex_type[256] = {
5911 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* @ABCDEFGHIJKLMNO */
5912 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* PQRSTUVWXYZ[\]^_ */
5913 +  0, 0, 0, LEX_HASH, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
5914 +  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */
5915 +  LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
5916 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */
5917 +  0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,      /* `abcdefghijklmno */
5918 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, LEX_TILDE, 0, /* pqrstuvwxyz{|}~.  */
5919 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5920 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5921 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5922 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5923 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5924 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5925 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5926 +  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
5927 +};
5928 +
5929 +/* In: a character.
5930 +   Out: 1 if this character ends a line.  */
5931 +char is_end_of_line[256] = {
5932 +#ifdef CR_EOL
5933 +  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,      /* @abcdefghijklmno */
5934 +#else
5935 +  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,      /* @abcdefghijklmno */
5936 +#endif
5937 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5938 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* _!"#$%&'()*+,-./ */
5939 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* 0123456789:;<=>? */
5940 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5941 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5942 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5943 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5944 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5945 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5946 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5947 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5948 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5949 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5950 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* */
5951 +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0       /* */
5952 +};
5953 +
5954 +#ifndef TC_CASE_SENSITIVE
5955 +char original_case_string[128];
5956 +#endif
5957 +
5958 +/* Functions private to this file.  */
5959 +
5960 +static char *buffer;   /* 1st char of each buffer of lines is here.  */
5961 +static char *buffer_limit;     /*->1 + last char in buffer.  */
5962 +
5963 +/* TARGET_BYTES_BIG_ENDIAN is required to be defined to either 0 or 1
5964 +   in the tc-<CPU>.h file.  See the "Porting GAS" section of the
5965 +   internals manual.  */
5966 +int target_big_endian = TARGET_BYTES_BIG_ENDIAN;
5967 +
5968 +/* Variables for handling include file directory table.  */
5969 +
5970 +/* Table of pointers to directories to search for .include's.  */
5971 +char **include_dirs;
5972 +
5973 +/* How many are in the table.  */
5974 +int include_dir_count;
5975 +
5976 +/* Length of longest in table.  */
5977 +int include_dir_maxlen = 1;
5978 +
5979 +#ifndef WORKING_DOT_WORD
5980 +struct broken_word *broken_words;
5981 +int new_broken_words;
5982 +#endif
5983 +
5984 +/* The current offset into the absolute section.  We don't try to
5985 +   build frags in the absolute section, since no data can be stored
5986 +   there.  We just keep track of the current offset.  */
5987 +addressT abs_section_offset;
5988 +
5989 +/* If this line had an MRI style label, it is stored in this variable.
5990 +   This is used by some of the MRI pseudo-ops.  */
5991 +symbolS *line_label;
5992 +
5993 +/* This global variable is used to support MRI common sections.  We
5994 +   translate such sections into a common symbol.  This variable is
5995 +   non-NULL when we are in an MRI common section.  */
5996 +symbolS *mri_common_symbol;
5997 +
5998 +/* In MRI mode, after a dc.b pseudo-op with an odd number of bytes, we
5999 +   need to align to an even byte boundary unless the next pseudo-op is
6000 +   dc.b, ds.b, or dcb.b.  This variable is set to 1 if an alignment
6001 +   may be needed.  */
6002 +static int mri_pending_align;
6003 +
6004 +#ifndef NO_LISTING
6005 +#ifdef OBJ_ELF
6006 +/* This variable is set to be non-zero if the next string we see might
6007 +   be the name of the source file in DWARF debugging information.  See
6008 +   the comment in emit_expr for the format we look for.  */
6009 +static int dwarf_file_string;
6010 +#endif
6011 +#endif
6012 +
6013 +static void do_s_func (int end_p, const char *default_prefix);
6014 +static void do_align (int, char *, int, int);
6015 +static void s_align (int, int);
6016 +static void s_altmacro (int);
6017 +static void s_bad_end (int);
6018 +static int hex_float (int, char *);
6019 +static segT get_known_segmented_expression (expressionS * expP);
6020 +static void pobegin (void);
6021 +static int get_line_sb (sb *);
6022 +static void generate_file_debug (void);
6023 +static char *_find_end_of_line (char *, int, int);
6024 +\f
6025 +void
6026 +read_begin (void)
6027 +{
6028 +  const char *p;
6029 +
6030 +  pobegin ();
6031 +  obj_read_begin_hook ();
6032 +
6033 +  /* Something close -- but not too close -- to a multiple of 1024.
6034 +     The debugging malloc I'm using has 24 bytes of overhead.  */
6035 +  obstack_begin (&notes, chunksize);
6036 +  obstack_begin (&cond_obstack, chunksize);
6037 +
6038 +  /* Use machine dependent syntax.  */
6039 +  for (p = line_separator_chars; *p; p++)
6040 +    is_end_of_line[(unsigned char) *p] = 1;
6041 +  /* Use more.  FIXME-SOMEDAY.  */
6042 +
6043 +  if (flag_mri)
6044 +    lex_type['?'] = 3;
6045 +}
6046 +\f
6047 +#ifndef TC_ADDRESS_BYTES
6048 +#ifdef BFD_ASSEMBLER
6049 +#define TC_ADDRESS_BYTES address_bytes
6050 +
6051 +static inline int
6052 +address_bytes (void)
6053 +{
6054 +  /* Choose smallest of 1, 2, 4, 8 bytes that is large enough to
6055 +     contain an address.  */
6056 +  int n = (stdoutput->arch_info->bits_per_address - 1) / 8;
6057 +  n |= n >> 1;
6058 +  n |= n >> 2;
6059 +  n += 1;
6060 +  return n;
6061 +}
6062 +#endif
6063 +#endif
6064 +
6065 +/* Set up pseudo-op tables.  */
6066 +
6067 +static struct hash_control *po_hash;
6068 +
6069 +static const pseudo_typeS potable[] = {
6070 +  {"abort", s_abort, 0},
6071 +  {"align", s_align_ptwo, 0},
6072 +  {"altmacro", s_altmacro, 1},
6073 +  {"ascii", stringer, 0},
6074 +  {"asciz", stringer, 1},
6075 +  {"balign", s_align_bytes, 0},
6076 +  {"balignw", s_align_bytes, -2},
6077 +  {"balignl", s_align_bytes, -4},
6078 +/* block  */
6079 +  {"byte", cons, 1},
6080 +  {"comm", s_comm, 0},
6081 +  {"common", s_mri_common, 0},
6082 +  {"common.s", s_mri_common, 1},
6083 +  {"data", s_data, 0},
6084 +  {"dc", cons, 2},
6085 +#ifdef TC_ADDRESS_BYTES
6086 +  {"dc.a", cons, 0},
6087 +#endif
6088 +  {"dc.b", cons, 1},
6089 +  {"dc.d", float_cons, 'd'},
6090 +  {"dc.l", cons, 4},
6091 +  {"dc.s", float_cons, 'f'},
6092 +  {"dc.w", cons, 2},
6093 +  {"dc.x", float_cons, 'x'},
6094 +  {"dcb", s_space, 2},
6095 +  {"dcb.b", s_space, 1},
6096 +  {"dcb.d", s_float_space, 'd'},
6097 +  {"dcb.l", s_space, 4},
6098 +  {"dcb.s", s_float_space, 'f'},
6099 +  {"dcb.w", s_space, 2},
6100 +  {"dcb.x", s_float_space, 'x'},
6101 +  {"ds", s_space, 2},
6102 +  {"ds.b", s_space, 1},
6103 +  {"ds.d", s_space, 8},
6104 +  {"ds.l", s_space, 4},
6105 +  {"ds.p", s_space, 12},
6106 +  {"ds.s", s_space, 4},
6107 +  {"ds.w", s_space, 2},
6108 +  {"ds.x", s_space, 12},
6109 +  {"debug", s_ignore, 0},
6110 +#ifdef S_SET_DESC
6111 +  {"desc", s_desc, 0},
6112 +#endif
6113 +/* dim  */
6114 +  {"double", float_cons, 'd'},
6115 +/* dsect  */
6116 +  {"eject", listing_eject, 0}, /* Formfeed listing.  */
6117 +  {"else", s_else, 0},
6118 +  {"elsec", s_else, 0},
6119 +  {"elseif", s_elseif, (int) O_ne},
6120 +  {"end", s_end, 0},
6121 +  {"endc", s_endif, 0},
6122 +  {"endfunc", s_func, 1},
6123 +  {"endif", s_endif, 0},
6124 +  {"endm", s_bad_end, 0},
6125 +  {"endr", s_bad_end, 1},
6126 +/* endef  */
6127 +  {"equ", s_set, 0},
6128 +  {"equiv", s_set, 1},
6129 +  {"err", s_err, 0},
6130 +  {"error", s_errwarn, 1},
6131 +  {"exitm", s_mexit, 0},
6132 +/* extend  */
6133 +  {"extern", s_ignore, 0},     /* We treat all undef as ext.  */
6134 +  {"appfile", s_app_file, 1},
6135 +  {"appline", s_app_line, 0},
6136 +  {"fail", s_fail, 0},
6137 +  {"file", s_app_file, 0},
6138 +  {"fill", s_fill, 0},
6139 +  {"float", float_cons, 'f'},
6140 +  {"format", s_ignore, 0},
6141 +  {"func", s_func, 0},
6142 +  {"global", s_globl, 0},
6143 +  {"globl", s_globl, 0},
6144 +  {"hword", cons, 2},
6145 +  {"if", s_if, (int) O_ne},
6146 +  {"ifb", s_ifb, 1},
6147 +  {"ifc", s_ifc, 0},
6148 +  {"ifdef", s_ifdef, 0},
6149 +  {"ifeq", s_if, (int) O_eq},
6150 +  {"ifeqs", s_ifeqs, 0},
6151 +  {"ifge", s_if, (int) O_ge},
6152 +  {"ifgt", s_if, (int) O_gt},
6153 +  {"ifle", s_if, (int) O_le},
6154 +  {"iflt", s_if, (int) O_lt},
6155 +  {"ifnb", s_ifb, 0},
6156 +  {"ifnc", s_ifc, 1},
6157 +  {"ifndef", s_ifdef, 1},
6158 +  {"ifne", s_if, (int) O_ne},
6159 +  {"ifnes", s_ifeqs, 1},
6160 +  {"ifnotdef", s_ifdef, 1},
6161 +  {"incbin", s_incbin, 0},
6162 +  {"include", s_include, 0},
6163 +  {"int", cons, 4},
6164 +  {"irp", s_irp, 0},
6165 +  {"irep", s_irp, 0},
6166 +  {"irpc", s_irp, 1},
6167 +  {"irepc", s_irp, 1},
6168 +  {"lcomm", s_lcomm, 0},
6169 +  {"lflags", listing_flags, 0},        /* Listing flags.  */
6170 +  {"linkonce", s_linkonce, 0},
6171 +  {"list", listing_list, 1},   /* Turn listing on.  */
6172 +  {"llen", listing_psize, 1},
6173 +  {"long", cons, 4},
6174 +  {"lsym", s_lsym, 0},
6175 +  {"macro", s_macro, 0},
6176 +  {"mexit", s_mexit, 0},
6177 +  {"mri", s_mri, 0},
6178 +  {".mri", s_mri, 0},  /* Special case so .mri works in MRI mode.  */
6179 +  {"name", s_ignore, 0},
6180 +  {"noaltmacro", s_altmacro, 0},
6181 +  {"noformat", s_ignore, 0},
6182 +  {"nolist", listing_list, 0}, /* Turn listing off.  */
6183 +  {"nopage", listing_nopage, 0},
6184 +  {"octa", cons, 16},
6185 +  {"offset", s_struct, 0},
6186 +  {"org", s_org, 0},
6187 +  {"p2align", s_align_ptwo, 0},
6188 +  {"p2alignw", s_align_ptwo, -2},
6189 +  {"p2alignl", s_align_ptwo, -4},
6190 +  {"page", listing_eject, 0},
6191 +  {"plen", listing_psize, 0},
6192 +  {"print", s_print, 0},
6193 +  {"psize", listing_psize, 0}, /* Set paper size.  */
6194 +  {"purgem", s_purgem, 0},
6195 +  {"quad", cons, 8},
6196 +  {"rep", s_rept, 0},
6197 +  {"rept", s_rept, 0},
6198 +  {"rva", s_rva, 4},
6199 +  {"sbttl", listing_title, 1}, /* Subtitle of listing.  */
6200 +/* scl  */
6201 +/* sect  */
6202 +  {"set", s_set, 0},
6203 +  {"short", cons, 2},
6204 +  {"single", float_cons, 'f'},
6205 +/* size  */
6206 +  {"space", s_space, 0},
6207 +  {"skip", s_space, 0},
6208 +  {"sleb128", s_leb128, 1},
6209 +  {"spc", s_ignore, 0},
6210 +  {"stabd", s_stab, 'd'},
6211 +  {"stabn", s_stab, 'n'},
6212 +  {"stabs", s_stab, 's'},
6213 +  {"string", stringer, 1},
6214 +  {"struct", s_struct, 0},
6215 +/* tag  */
6216 +  {"text", s_text, 0},
6217 +
6218 +  /* This is for gcc to use.  It's only just been added (2/94), so gcc
6219 +     won't be able to use it for a while -- probably a year or more.
6220 +     But once this has been released, check with gcc maintainers
6221 +     before deleting it or even changing the spelling.  */
6222 +  {"this_GCC_requires_the_GNU_assembler", s_ignore, 0},
6223 +  /* If we're folding case -- done for some targets, not necessarily
6224 +     all -- the above string in an input file will be converted to
6225 +     this one.  Match it either way...  */
6226 +  {"this_gcc_requires_the_gnu_assembler", s_ignore, 0},
6227 +
6228 +  {"title", listing_title, 0}, /* Listing title.  */
6229 +  {"ttl", listing_title, 0},
6230 +/* type  */
6231 +  {"uleb128", s_leb128, 0},
6232 +/* use  */
6233 +/* val  */
6234 +  {"xcom", s_comm, 0},
6235 +  {"xdef", s_globl, 0},
6236 +  {"xref", s_ignore, 0},
6237 +  {"xstabs", s_xstab, 's'},
6238 +  {"warning", s_errwarn, 0},
6239 +  {"word", cons, 2},
6240 +  {"zero", s_space, 0},
6241 +  {NULL, NULL, 0}                      /* End sentinel.  */
6242 +};
6243 +
6244 +static offsetT
6245 +get_absolute_expr (expressionS *exp)
6246 +{
6247 +  expression (exp);
6248 +  if (exp->X_op != O_constant)
6249 +    {
6250 +      if (exp->X_op != O_absent)
6251 +       as_bad (_("bad or irreducible absolute expression"));
6252 +      exp->X_add_number = 0;
6253 +    }
6254 +  return exp->X_add_number;
6255 +}
6256 +
6257 +offsetT
6258 +get_absolute_expression (void)
6259 +{
6260 +  expressionS exp;
6261 +
6262 +  return get_absolute_expr (&exp);
6263 +}
6264 +
6265 +static int pop_override_ok = 0;
6266 +static const char *pop_table_name;
6267 +
6268 +void
6269 +pop_insert (const pseudo_typeS *table)
6270 +{
6271 +  const char *errtxt;
6272 +  const pseudo_typeS *pop;
6273 +  for (pop = table; pop->poc_name; pop++)
6274 +    {
6275 +      errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
6276 +      if (errtxt && (!pop_override_ok || strcmp (errtxt, "exists")))
6277 +       as_fatal (_("error constructing %s pseudo-op table: %s"), pop_table_name,
6278 +                 errtxt);
6279 +    }
6280 +}
6281 +
6282 +#ifndef md_pop_insert
6283 +#define md_pop_insert()                pop_insert(md_pseudo_table)
6284 +#endif
6285 +
6286 +#ifndef obj_pop_insert
6287 +#define obj_pop_insert()       pop_insert(obj_pseudo_table)
6288 +#endif
6289 +
6290 +#ifndef cfi_pop_insert
6291 +#define cfi_pop_insert()       pop_insert(cfi_pseudo_table)
6292 +#endif
6293 +
6294 +static void
6295 +pobegin (void)
6296 +{
6297 +  po_hash = hash_new ();
6298 +
6299 +  /* Do the target-specific pseudo ops.  */
6300 +  pop_table_name = "md";
6301 +  md_pop_insert ();
6302 +
6303 +  /* Now object specific.  Skip any that were in the target table.  */
6304 +  pop_table_name = "obj";
6305 +  pop_override_ok = 1;
6306 +  obj_pop_insert ();
6307 +
6308 +  /* Now portable ones.  Skip any that we've seen already.  */
6309 +  pop_table_name = "standard";
6310 +  pop_insert (potable);
6311 +
6312 +#ifdef TARGET_USE_CFIPOP
6313 +  pop_table_name = "cfi";
6314 +  pop_override_ok = 1;
6315 +  cfi_pop_insert ();
6316 +#endif
6317 +}
6318 +\f
6319 +#define HANDLE_CONDITIONAL_ASSEMBLY()                                  \
6320 +  if (ignore_input ())                                                 \
6321 +    {                                                                  \
6322 +      char *eol = find_end_of_line (input_line_pointer, flag_m68k_mri);        \
6323 +      input_line_pointer = (input_line_pointer <= buffer_limit         \
6324 +                           && eol >= buffer_limit)                     \
6325 +                          ? buffer_limit                               \
6326 +                          : eol + 1;                                   \
6327 +      continue;                                                                \
6328 +    }
6329 +
6330 +/* This function is used when scrubbing the characters between #APP
6331 +   and #NO_APP.  */
6332 +
6333 +static char *scrub_string;
6334 +static char *scrub_string_end;
6335 +
6336 +static int
6337 +scrub_from_string (char *buf, int buflen)
6338 +{
6339 +  int copy;
6340 +
6341 +  copy = scrub_string_end - scrub_string;
6342 +  if (copy > buflen)
6343 +    copy = buflen;
6344 +  memcpy (buf, scrub_string, copy);
6345 +  scrub_string += copy;
6346 +  return copy;
6347 +}
6348 +
6349 +/* Helper function of read_a_source_file, which tries to expand a macro.  */
6350 +static int
6351 +try_macro (char term, const char *line)
6352 +{
6353 +  sb out;
6354 +  const char *err;
6355 +  macro_entry *macro;
6356 +
6357 +  if (check_macro (line, &out, &err, &macro))
6358 +    {
6359 +      if (err != NULL)
6360 +       as_bad ("%s", err);
6361 +      *input_line_pointer++ = term;
6362 +      input_scrub_include_sb (&out,
6363 +                             input_line_pointer, 1);
6364 +      sb_kill (&out);
6365 +      buffer_limit =
6366 +       input_scrub_next_buffer (&input_line_pointer);
6367 +#ifdef md_macro_info
6368 +      md_macro_info (macro);
6369 +#endif
6370 +      return 1;
6371 +    }
6372 +  return 0;
6373 +}
6374 +
6375 +/* We read the file, putting things into a web that represents what we
6376 +   have been reading.  */
6377 +void
6378 +read_a_source_file (char *name)
6379 +{
6380 +  register char c;
6381 +  register char *s;            /* String of symbol, '\0' appended.  */
6382 +  register int temp;
6383 +  pseudo_typeS *pop;
6384 +
6385 +#ifdef WARN_COMMENTS
6386 +  found_comment = 0;
6387 +#endif
6388 +
6389 +  buffer = input_scrub_new_file (name);
6390 +
6391 +  listing_file (name);
6392 +  listing_newline (NULL);
6393 +  register_dependency (name);
6394 +
6395 +  /* Generate debugging information before we've read anything in to denote
6396 +     this file as the "main" source file and not a subordinate one
6397 +     (e.g. N_SO vs N_SOL in stabs).  */
6398 +  generate_file_debug ();
6399 +
6400 +  while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
6401 +    {                          /* We have another line to parse.  */
6402 +#ifndef NO_LISTING
6403 +      /* In order to avoid listing macro expansion lines with labels
6404 +        multiple times, keep track of which line was last issued.  */
6405 +      static char *last_eol;
6406 +
6407 +      last_eol = NULL;
6408 +#endif
6409 +      know (buffer_limit[-1] == '\n'); /* Must have a sentinel.  */
6410 +
6411 +      while (input_line_pointer < buffer_limit)
6412 +       {
6413 +         /* We have more of this buffer to parse.  */
6414 +
6415 +         /* We now have input_line_pointer->1st char of next line.
6416 +            If input_line_pointer [-1] == '\n' then we just
6417 +            scanned another line: so bump line counters.  */
6418 +         if (is_end_of_line[(unsigned char) input_line_pointer[-1]])
6419 +           {
6420 +#ifdef md_start_line_hook
6421 +             md_start_line_hook ();
6422 +#endif
6423 +             if (input_line_pointer[-1] == '\n')
6424 +               bump_line_counters ();
6425 +
6426 +             line_label = NULL;
6427 +
6428 +             if (LABELS_WITHOUT_COLONS || flag_m68k_mri)
6429 +               {
6430 +                 /* Text at the start of a line must be a label, we
6431 +                    run down and stick a colon in.  */
6432 +                 if (is_name_beginner (*input_line_pointer))
6433 +                   {
6434 +                     char *line_start = input_line_pointer;
6435 +                     char c;
6436 +                     int mri_line_macro;
6437 +
6438 +                     LISTING_NEWLINE ();
6439 +                     HANDLE_CONDITIONAL_ASSEMBLY ();
6440 +
6441 +                     c = get_symbol_end ();
6442 +
6443 +                     /* In MRI mode, the EQU and MACRO pseudoops must
6444 +                        be handled specially.  */
6445 +                     mri_line_macro = 0;
6446 +                     if (flag_m68k_mri)
6447 +                       {
6448 +                         char *rest = input_line_pointer + 1;
6449 +
6450 +                         if (*rest == ':')
6451 +                           ++rest;
6452 +                         if (*rest == ' ' || *rest == '\t')
6453 +                           ++rest;
6454 +                         if ((strncasecmp (rest, "EQU", 3) == 0
6455 +                              || strncasecmp (rest, "SET", 3) == 0)
6456 +                             && (rest[3] == ' ' || rest[3] == '\t'))
6457 +                           {
6458 +                             input_line_pointer = rest + 3;
6459 +                             equals (line_start,
6460 +                                     strncasecmp (rest, "SET", 3) == 0);
6461 +                             continue;
6462 +                           }
6463 +                         if (strncasecmp (rest, "MACRO", 5) == 0
6464 +                             && (rest[5] == ' '
6465 +                                 || rest[5] == '\t'
6466 +                                 || is_end_of_line[(unsigned char) rest[5]]))
6467 +                           mri_line_macro = 1;
6468 +                       }
6469 +
6470 +                     /* In MRI mode, we need to handle the MACRO
6471 +                        pseudo-op specially: we don't want to put the
6472 +                        symbol in the symbol table.  */
6473 +                     if (!mri_line_macro
6474 +#ifdef TC_START_LABEL_WITHOUT_COLON
6475 +                         && TC_START_LABEL_WITHOUT_COLON(c,
6476 +                                                         input_line_pointer)
6477 +#endif
6478 +                         )
6479 +                       line_label = colon (line_start);
6480 +                     else
6481 +                       line_label = symbol_create (line_start,
6482 +                                                   absolute_section,
6483 +                                                   (valueT) 0,
6484 +                                                   &zero_address_frag);
6485 +
6486 +                     *input_line_pointer = c;
6487 +                     if (c == ':')
6488 +                       input_line_pointer++;
6489 +                   }
6490 +               }
6491 +           }
6492 +
6493 +         /* We are at the beginning of a line, or similar place.
6494 +            We expect a well-formed assembler statement.
6495 +            A "symbol-name:" is a statement.
6496 +
6497 +            Depending on what compiler is used, the order of these tests
6498 +            may vary to catch most common case 1st.
6499 +            Each test is independent of all other tests at the (top) level.
6500 +            PLEASE make a compiler that doesn't use this assembler.
6501 +            It is crufty to waste a compiler's time encoding things for this
6502 +            assembler, which then wastes more time decoding it.
6503 +            (And communicating via (linear) files is silly!
6504 +            If you must pass stuff, please pass a tree!)  */
6505 +         if ((c = *input_line_pointer++) == '\t'
6506 +             || c == ' '
6507 +             || c == '\f'
6508 +             || c == 0)
6509 +           c = *input_line_pointer++;
6510 +
6511 +         know (c != ' ');      /* No further leading whitespace.  */
6512 +
6513 +#ifndef NO_LISTING
6514 +         /* If listing is on, and we are expanding a macro, then give
6515 +            the listing code the contents of the expanded line.  */
6516 +         if (listing)
6517 +           {
6518 +             if ((listing & LISTING_MACEXP) && macro_nest > 0)
6519 +               {
6520 +                 char *copy;
6521 +                 int len;
6522 +
6523 +                 /* Find the end of the current expanded macro line.  */
6524 +                 s = find_end_of_line (input_line_pointer - 1, flag_m68k_mri);
6525 +
6526 +                 if (s != last_eol)
6527 +                   {
6528 +                     last_eol = s;
6529 +                     /* Copy it for safe keeping.  Also give an indication of
6530 +                        how much macro nesting is involved at this point.  */
6531 +                     len = s - (input_line_pointer - 1);
6532 +                     copy = (char *) xmalloc (len + macro_nest + 2);
6533 +                     memset (copy, '>', macro_nest);
6534 +                     copy[macro_nest] = ' ';
6535 +                     memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
6536 +                     copy[macro_nest + 1 + len] = '\0';
6537 +
6538 +                     /* Install the line with the listing facility.  */
6539 +                     listing_newline (copy);
6540 +                   }
6541 +               }
6542 +             else
6543 +               listing_newline (NULL);
6544 +           }
6545 +#endif
6546 +         /* C is the 1st significant character.
6547 +            Input_line_pointer points after that character.  */
6548 +         if (is_name_beginner (c))
6549 +           {
6550 +             /* Want user-defined label or pseudo/opcode.  */
6551 +             HANDLE_CONDITIONAL_ASSEMBLY ();
6552 +
6553 +             s = --input_line_pointer;
6554 +             c = get_symbol_end ();    /* name's delimiter.  */
6555 +
6556 +             /* C is character after symbol.
6557 +                That character's place in the input line is now '\0'.
6558 +                S points to the beginning of the symbol.
6559 +                  [In case of pseudo-op, s->'.'.]
6560 +                Input_line_pointer->'\0' where c was.  */
6561 +             if (TC_START_LABEL (c, input_line_pointer))
6562 +               {
6563 +                 if (flag_m68k_mri)
6564 +                   {
6565 +                     char *rest = input_line_pointer + 1;
6566 +
6567 +                     /* In MRI mode, \tsym: set 0 is permitted.  */
6568 +                     if (*rest == ':')
6569 +                       ++rest;
6570 +
6571 +                     if (*rest == ' ' || *rest == '\t')
6572 +                       ++rest;
6573 +
6574 +                     if ((strncasecmp (rest, "EQU", 3) == 0
6575 +                          || strncasecmp (rest, "SET", 3) == 0)
6576 +                         && (rest[3] == ' ' || rest[3] == '\t'))
6577 +                       {
6578 +                         input_line_pointer = rest + 3;
6579 +                         equals (s, 1);
6580 +                         continue;
6581 +                       }
6582 +                   }
6583 +
6584 +                 line_label = colon (s);       /* User-defined label.  */
6585 +                 /* Put ':' back for error messages' sake.  */
6586 +                 *input_line_pointer++ = ':';
6587 +#ifdef tc_check_label
6588 +                 tc_check_label (line_label);
6589 +#endif
6590 +                 /* Input_line_pointer->after ':'.  */
6591 +                 SKIP_WHITESPACE ();
6592 +               }
6593 +              else if ((c == '='
6594 +                       || ((c == ' ' || c == '\t')
6595 +                            && input_line_pointer[1] == '='))
6596 +#ifdef TC_EQUAL_IN_INSN
6597 +                           && !TC_EQUAL_IN_INSN (c, s)
6598 +#endif
6599 +                           )
6600 +               {
6601 +                 equals (s, 1);
6602 +                 demand_empty_rest_of_line ();
6603 +               }
6604 +             else
6605 +               {
6606 +                 /* Expect pseudo-op or machine instruction.  */
6607 +                 pop = NULL;
6608 +
6609 +#ifndef TC_CASE_SENSITIVE
6610 +                 {
6611 +                   char *s2 = s;
6612 +
6613 +                   strncpy (original_case_string, s2, sizeof (original_case_string));
6614 +                   original_case_string[sizeof (original_case_string) - 1] = 0;
6615 +
6616 +                   while (*s2)
6617 +                     {
6618 +                       *s2 = TOLOWER (*s2);
6619 +                       s2++;
6620 +                     }
6621 +                 }
6622 +#endif
6623 +                 if (NO_PSEUDO_DOT || flag_m68k_mri)
6624 +                   {
6625 +                     /* The MRI assembler and the m88k use pseudo-ops
6626 +                        without a period.  */
6627 +                     pop = (pseudo_typeS *) hash_find (po_hash, s);
6628 +                     if (pop != NULL && pop->poc_handler == NULL)
6629 +                       pop = NULL;
6630 +                   }
6631 +
6632 +                 if (pop != NULL
6633 +                     || (!flag_m68k_mri && *s == '.'))
6634 +                   {
6635 +                     /* PSEUDO - OP.
6636 +
6637 +                        WARNING: c has next char, which may be end-of-line.
6638 +                        We lookup the pseudo-op table with s+1 because we
6639 +                        already know that the pseudo-op begins with a '.'.  */
6640 +
6641 +                     if (pop == NULL)
6642 +                       pop = (pseudo_typeS *) hash_find (po_hash, s + 1);
6643 +                     if (pop && !pop->poc_handler)
6644 +                       pop = NULL;
6645 +
6646 +                     /* In MRI mode, we may need to insert an
6647 +                        automatic alignment directive.  What a hack
6648 +                        this is.  */
6649 +                     if (mri_pending_align
6650 +                         && (pop == NULL
6651 +                             || !((pop->poc_handler == cons
6652 +                                   && pop->poc_val == 1)
6653 +                                  || (pop->poc_handler == s_space
6654 +                                      && pop->poc_val == 1)
6655 +#ifdef tc_conditional_pseudoop
6656 +                                  || tc_conditional_pseudoop (pop)
6657 +#endif
6658 +                                  || pop->poc_handler == s_if
6659 +                                  || pop->poc_handler == s_ifdef
6660 +                                  || pop->poc_handler == s_ifc
6661 +                                  || pop->poc_handler == s_ifeqs
6662 +                                  || pop->poc_handler == s_else
6663 +                                  || pop->poc_handler == s_endif
6664 +                                  || pop->poc_handler == s_globl
6665 +                                  || pop->poc_handler == s_ignore)))
6666 +                       {
6667 +                         do_align (1, (char *) NULL, 0, 0);
6668 +                         mri_pending_align = 0;
6669 +
6670 +                         if (line_label != NULL)
6671 +                           {
6672 +                             symbol_set_frag (line_label, frag_now);
6673 +                             S_SET_VALUE (line_label, frag_now_fix ());
6674 +                           }
6675 +                       }
6676 +
6677 +                     /* Print the error msg now, while we still can.  */
6678 +                     if (pop == NULL)
6679 +                       {
6680 +                         char *end = input_line_pointer;
6681 +
6682 +                         *input_line_pointer = c;
6683 +                         s_ignore (0);
6684 +                         c = *--input_line_pointer;
6685 +                         *input_line_pointer = '\0';
6686 +                         if (! macro_defined || ! try_macro (c, s))
6687 +                           {
6688 +                             *end = '\0';
6689 +                             as_bad (_("unknown pseudo-op: `%s'"), s);
6690 +                             *input_line_pointer++ = c;
6691 +                           }
6692 +                         continue;
6693 +                       }
6694 +
6695 +                     /* Put it back for error messages etc.  */
6696 +                     *input_line_pointer = c;
6697 +                     /* The following skip of whitespace is compulsory.
6698 +                        A well shaped space is sometimes all that separates
6699 +                        keyword from operands.  */
6700 +                     if (c == ' ' || c == '\t')
6701 +                       input_line_pointer++;
6702 +
6703 +                     /* Input_line is restored.
6704 +                        Input_line_pointer->1st non-blank char
6705 +                        after pseudo-operation.  */
6706 +                     (*pop->poc_handler) (pop->poc_val);
6707 +
6708 +                     /* If that was .end, just get out now.  */
6709 +                     if (pop->poc_handler == s_end)
6710 +                       goto quit;
6711 +                   }
6712 +                 else
6713 +                   {
6714 +                     /* WARNING: c has char, which may be end-of-line.  */
6715 +                     /* Also: input_line_pointer->`\0` where c was.  */
6716 +                     *input_line_pointer = c;
6717 +                     input_line_pointer = _find_end_of_line (input_line_pointer, flag_m68k_mri, 1);
6718 +                     c = *input_line_pointer;
6719 +                     *input_line_pointer = '\0';
6720 +
6721 +                     generate_lineno_debug ();
6722 +
6723 +                     if (macro_defined && try_macro (c, s))
6724 +                       continue;
6725 +
6726 +                     if (mri_pending_align)
6727 +                       {
6728 +                         do_align (1, (char *) NULL, 0, 0);
6729 +                         mri_pending_align = 0;
6730 +                         if (line_label != NULL)
6731 +                           {
6732 +                             symbol_set_frag (line_label, frag_now);
6733 +                             S_SET_VALUE (line_label, frag_now_fix ());
6734 +                           }
6735 +                       }
6736 +
6737 +                     md_assemble (s);  /* Assemble 1 instruction.  */
6738 +
6739 +                     *input_line_pointer++ = c;
6740 +
6741 +                     /* We resume loop AFTER the end-of-line from
6742 +                        this instruction.  */
6743 +                   }
6744 +               }
6745 +             continue;
6746 +           }
6747 +
6748 +         /* Empty statement?  */
6749 +         if (is_end_of_line[(unsigned char) c])
6750 +           continue;
6751 +
6752 +         if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB) && ISDIGIT (c))
6753 +           {
6754 +             /* local label  ("4:")  */
6755 +             char *backup = input_line_pointer;
6756 +
6757 +             HANDLE_CONDITIONAL_ASSEMBLY ();
6758 +
6759 +             temp = c - '0';
6760 +
6761 +             /* Read the whole number.  */
6762 +             while (ISDIGIT (*input_line_pointer))
6763 +               {
6764 +                 temp = (temp * 10) + *input_line_pointer - '0';
6765 +                 ++input_line_pointer;
6766 +               }
6767 +
6768 +             if (LOCAL_LABELS_DOLLAR
6769 +                 && *input_line_pointer == '$'
6770 +                 && *(input_line_pointer + 1) == ':')
6771 +               {
6772 +                 input_line_pointer += 2;
6773 +
6774 +                 if (dollar_label_defined (temp))
6775 +                   {
6776 +                     as_fatal (_("label \"%d$\" redefined"), temp);
6777 +                   }
6778 +
6779 +                 define_dollar_label (temp);
6780 +                 colon (dollar_label_name (temp, 0));
6781 +                 continue;
6782 +               }
6783 +
6784 +             if (LOCAL_LABELS_FB
6785 +                 && *input_line_pointer++ == ':')
6786 +               {
6787 +                 fb_label_instance_inc (temp);
6788 +                 colon (fb_label_name (temp, 0));
6789 +                 continue;
6790 +               }
6791 +
6792 +             input_line_pointer = backup;
6793 +           }                   /* local label  ("4:") */
6794 +
6795 +         if (c && strchr (line_comment_chars, c))
6796 +           {                   /* Its a comment.  Better say APP or NO_APP.  */
6797 +             sb sbuf;
6798 +             char *ends;
6799 +             char *new_buf;
6800 +             char *new_tmp;
6801 +             unsigned int new_length;
6802 +             char *tmp_buf = 0;
6803 +
6804 +             bump_line_counters ();
6805 +             s = input_line_pointer;
6806 +             if (strncmp (s, "APP\n", 4))
6807 +               continue;       /* We ignore it */
6808 +             s += 4;
6809 +
6810 +             sb_new (&sbuf);
6811 +             ends = strstr (s, "#NO_APP\n");
6812 +
6813 +             if (!ends)
6814 +               {
6815 +                 unsigned int tmp_len;
6816 +                 unsigned int num;
6817 +
6818 +                 /* The end of the #APP wasn't in this buffer.  We
6819 +                    keep reading in buffers until we find the #NO_APP
6820 +                    that goes with this #APP  There is one.  The specs
6821 +                    guarantee it...  */
6822 +                 tmp_len = buffer_limit - s;
6823 +                 tmp_buf = xmalloc (tmp_len + 1);
6824 +                 memcpy (tmp_buf, s, tmp_len);
6825 +                 do
6826 +                   {
6827 +                     new_tmp = input_scrub_next_buffer (&buffer);
6828 +                     if (!new_tmp)
6829 +                       break;
6830 +                     else
6831 +                       buffer_limit = new_tmp;
6832 +                     input_line_pointer = buffer;
6833 +                     ends = strstr (buffer, "#NO_APP\n");
6834 +                     if (ends)
6835 +                       num = ends - buffer;
6836 +                     else
6837 +                       num = buffer_limit - buffer;
6838 +
6839 +                     tmp_buf = xrealloc (tmp_buf, tmp_len + num);
6840 +                     memcpy (tmp_buf + tmp_len, buffer, num);
6841 +                     tmp_len += num;
6842 +                   }
6843 +                 while (!ends);
6844 +
6845 +                 input_line_pointer = ends ? ends + 8 : NULL;
6846 +
6847 +                 s = tmp_buf;
6848 +                 ends = s + tmp_len;
6849 +
6850 +               }
6851 +             else
6852 +               {
6853 +                 input_line_pointer = ends + 8;
6854 +               }
6855 +
6856 +             scrub_string = s;
6857 +             scrub_string_end = ends;
6858 +
6859 +             new_length = ends - s;
6860 +             new_buf = (char *) xmalloc (new_length);
6861 +             new_tmp = new_buf;
6862 +             for (;;)
6863 +               {
6864 +                 int space;
6865 +                 int size;
6866 +
6867 +                 space = (new_buf + new_length) - new_tmp;
6868 +                 size = do_scrub_chars (scrub_from_string, new_tmp, space);
6869 +
6870 +                 if (size < space)
6871 +                   {
6872 +                     new_tmp[size] = 0;
6873 +                     break;
6874 +                   }
6875 +
6876 +                 new_buf = xrealloc (new_buf, new_length + 100);
6877 +                 new_tmp = new_buf + new_length;
6878 +                 new_length += 100;
6879 +               }
6880 +
6881 +             if (tmp_buf)
6882 +               free (tmp_buf);
6883 +
6884 +             /* We've "scrubbed" input to the preferred format.  In the
6885 +                process we may have consumed the whole of the remaining
6886 +                file (and included files).  We handle this formatted
6887 +                input similar to that of macro expansion, letting
6888 +                actual macro expansion (possibly nested) and other
6889 +                input expansion work.  Beware that in messages, line
6890 +                numbers and possibly file names will be incorrect.  */
6891 +             sb_add_string (&sbuf, new_buf);
6892 +             input_scrub_include_sb (&sbuf, input_line_pointer, 0);
6893 +             sb_kill (&sbuf);
6894 +             buffer_limit = input_scrub_next_buffer (&input_line_pointer);
6895 +             free (new_buf);
6896 +             continue;
6897 +           }
6898 +
6899 +         HANDLE_CONDITIONAL_ASSEMBLY ();
6900 +
6901 +#ifdef tc_unrecognized_line
6902 +         if (tc_unrecognized_line (c))
6903 +           continue;
6904 +#endif
6905 +         input_line_pointer--;
6906 +         /* Report unknown char as ignored.  */
6907 +         demand_empty_rest_of_line ();
6908 +       }
6909 +
6910 +#ifdef md_after_pass_hook
6911 +      md_after_pass_hook ();
6912 +#endif
6913 +    }
6914 +
6915 + quit:
6916 +
6917 +#ifdef md_cleanup
6918 +  md_cleanup ();
6919 +#endif
6920 +  /* Close the input file.  */
6921 +  input_scrub_close ();
6922 +#ifdef WARN_COMMENTS
6923 +  {
6924 +    if (warn_comment && found_comment)
6925 +      as_warn_where (found_comment_file, found_comment,
6926 +                    "first comment found here");
6927 +  }
6928 +#endif
6929 +}
6930 +
6931 +/* Convert O_constant expression EXP into the equivalent O_big representation.
6932 +   Take the sign of the number from X_unsigned rather than X_add_number.  */
6933 +
6934 +static void
6935 +convert_to_bignum (expressionS *exp)
6936 +{
6937 +  valueT value;
6938 +  unsigned int i;
6939 +
6940 +  value = exp->X_add_number;
6941 +  for (i = 0; i < sizeof (exp->X_add_number) / CHARS_PER_LITTLENUM; i++)
6942 +    {
6943 +      generic_bignum[i] = value & LITTLENUM_MASK;
6944 +      value >>= LITTLENUM_NUMBER_OF_BITS;
6945 +    }
6946 +  /* Add a sequence of sign bits if the top bit of X_add_number is not
6947 +     the sign of the original value.  */
6948 +  if ((exp->X_add_number < 0) != !exp->X_unsigned)
6949 +    generic_bignum[i++] = exp->X_unsigned ? 0 : LITTLENUM_MASK;
6950 +  exp->X_op = O_big;
6951 +  exp->X_add_number = i;
6952 +}
6953 +
6954 +/* For most MRI pseudo-ops, the line actually ends at the first
6955 +   nonquoted space.  This function looks for that point, stuffs a null
6956 +   in, and sets *STOPCP to the character that used to be there, and
6957 +   returns the location.
6958 +
6959 +   Until I hear otherwise, I am going to assume that this is only true
6960 +   for the m68k MRI assembler.  */
6961 +
6962 +char *
6963 +mri_comment_field (char *stopcp)
6964 +{
6965 +  char *s;
6966 +#ifdef TC_M68K
6967 +  int inquote = 0;
6968 +
6969 +  know (flag_m68k_mri);
6970 +
6971 +  for (s = input_line_pointer;
6972 +       ((!is_end_of_line[(unsigned char) *s] && *s != ' ' && *s != '\t')
6973 +       || inquote);
6974 +       s++)
6975 +    {
6976 +      if (*s == '\'')
6977 +       inquote = !inquote;
6978 +    }
6979 +#else
6980 +  for (s = input_line_pointer;
6981 +       !is_end_of_line[(unsigned char) *s];
6982 +       s++)
6983 +    ;
6984 +#endif
6985 +  *stopcp = *s;
6986 +  *s = '\0';
6987 +
6988 +  return s;
6989 +}
6990 +
6991 +/* Skip to the end of an MRI comment field.  */
6992 +
6993 +void
6994 +mri_comment_end (char *stop, int stopc)
6995 +{
6996 +  know (flag_mri);
6997 +
6998 +  input_line_pointer = stop;
6999 +  *stop = stopc;
7000 +  while (!is_end_of_line[(unsigned char) *input_line_pointer])
7001 +    ++input_line_pointer;
7002 +}
7003 +
7004 +void
7005 +s_abort (int ignore ATTRIBUTE_UNUSED)
7006 +{
7007 +  as_fatal (_(".abort detected.  Abandoning ship."));
7008 +}
7009 +
7010 +/* Guts of .align directive.  N is the power of two to which to align.
7011 +   FILL may be NULL, or it may point to the bytes of the fill pattern.
7012 +   LEN is the length of whatever FILL points to, if anything.  MAX is
7013 +   the maximum number of characters to skip when doing the alignment,
7014 +   or 0 if there is no maximum.  */
7015 +
7016 +static void
7017 +do_align (int n, char *fill, int len, int max)
7018 +{
7019 +  if (now_seg == absolute_section)
7020 +    {
7021 +      if (fill != NULL)
7022 +       while (len-- > 0)
7023 +         if (*fill++ != '\0')
7024 +           {
7025 +             as_warn (_("ignoring fill value in absolute section"));
7026 +             break;
7027 +           }
7028 +      fill = NULL;
7029 +      len = 0;
7030 +    }
7031 +
7032 +#ifdef md_flush_pending_output
7033 +  md_flush_pending_output ();
7034 +#endif
7035 +#ifdef md_do_align
7036 +  md_do_align (n, fill, len, max, just_record_alignment);
7037 +#endif
7038 +
7039 +  /* Only make a frag if we HAVE to...  */
7040 +  if (n != 0 && !need_pass_2)
7041 +    {
7042 +      if (fill == NULL)
7043 +       {
7044 +         if (subseg_text_p (now_seg))
7045 +           frag_align_code (n, max);
7046 +         else
7047 +           frag_align (n, 0, max);
7048 +       }
7049 +      else if (len <= 1)
7050 +       frag_align (n, *fill, max);
7051 +      else
7052 +       frag_align_pattern (n, fill, len, max);
7053 +    }
7054 +
7055 +#ifdef md_do_align
7056 + just_record_alignment: ATTRIBUTE_UNUSED_LABEL
7057 +#endif
7058 +
7059 +  record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
7060 +}
7061 +
7062 +/* Handle the .align pseudo-op.  A positive ARG is a default alignment
7063 +   (in bytes).  A negative ARG is the negative of the length of the
7064 +   fill pattern.  BYTES_P is non-zero if the alignment value should be
7065 +   interpreted as the byte boundary, rather than the power of 2.  */
7066 +
7067 +#ifdef BFD_ASSEMBLER
7068 +#define ALIGN_LIMIT (stdoutput->arch_info->bits_per_address - 1)
7069 +#else
7070 +#define ALIGN_LIMIT 15
7071 +#endif
7072 +
7073 +static void
7074 +s_align (int arg, int bytes_p)
7075 +{
7076 +  unsigned int align_limit = ALIGN_LIMIT;
7077 +  unsigned int align;
7078 +  char *stop = NULL;
7079 +  char stopc;
7080 +  offsetT fill = 0;
7081 +  int max;
7082 +  int fill_p;
7083 +
7084 +  if (flag_mri)
7085 +    stop = mri_comment_field (&stopc);
7086 +
7087 +  if (is_end_of_line[(unsigned char) *input_line_pointer])
7088 +    {
7089 +      if (arg < 0)
7090 +       align = 0;
7091 +      else
7092 +       align = arg;    /* Default value from pseudo-op table.  */
7093 +    }
7094 +  else
7095 +    {
7096 +      align = get_absolute_expression ();
7097 +      SKIP_WHITESPACE ();
7098 +    }
7099 +
7100 +  if (bytes_p)
7101 +    {
7102 +      /* Convert to a power of 2.  */
7103 +      if (align != 0)
7104 +       {
7105 +         unsigned int i;
7106 +
7107 +         for (i = 0; (align & 1) == 0; align >>= 1, ++i)
7108 +           ;
7109 +         if (align != 1)
7110 +           as_bad (_("alignment not a power of 2"));
7111 +
7112 +         align = i;
7113 +       }
7114 +    }
7115 +
7116 +  if (align > align_limit)
7117 +    {
7118 +      align = align_limit;
7119 +      as_warn (_("alignment too large: %u assumed"), align);
7120 +    }
7121 +
7122 +  if (*input_line_pointer != ',')
7123 +    {
7124 +      fill_p = 0;
7125 +      max = 0;
7126 +    }
7127 +  else
7128 +    {
7129 +      ++input_line_pointer;
7130 +      if (*input_line_pointer == ',')
7131 +       fill_p = 0;
7132 +      else
7133 +       {
7134 +         fill = get_absolute_expression ();
7135 +         SKIP_WHITESPACE ();
7136 +         fill_p = 1;
7137 +       }
7138 +
7139 +      if (*input_line_pointer != ',')
7140 +       max = 0;
7141 +      else
7142 +       {
7143 +         ++input_line_pointer;
7144 +         max = get_absolute_expression ();
7145 +       }
7146 +    }
7147 +
7148 +  if (!fill_p)
7149 +    {
7150 +      if (arg < 0)
7151 +       as_warn (_("expected fill pattern missing"));
7152 +      do_align (align, (char *) NULL, 0, max);
7153 +    }
7154 +  else
7155 +    {
7156 +      int fill_len;
7157 +
7158 +      if (arg >= 0)
7159 +       fill_len = 1;
7160 +      else
7161 +       fill_len = -arg;
7162 +      if (fill_len <= 1)
7163 +       {
7164 +         char fill_char;
7165 +
7166 +         fill_char = fill;
7167 +         do_align (align, &fill_char, fill_len, max);
7168 +       }
7169 +      else
7170 +       {
7171 +         char ab[16];
7172 +
7173 +         if ((size_t) fill_len > sizeof ab)
7174 +           abort ();
7175 +         md_number_to_chars (ab, fill, fill_len);
7176 +         do_align (align, ab, fill_len, max);
7177 +       }
7178 +    }
7179 +
7180 +  demand_empty_rest_of_line ();
7181 +
7182 +  if (flag_mri)
7183 +    mri_comment_end (stop, stopc);
7184 +}
7185 +
7186 +/* Handle the .align pseudo-op on machines where ".align 4" means
7187 +   align to a 4 byte boundary.  */
7188 +
7189 +void
7190 +s_align_bytes (int arg)
7191 +{
7192 +  s_align (arg, 1);
7193 +}
7194 +
7195 +/* Handle the .align pseudo-op on machines where ".align 4" means align
7196 +   to a 2**4 boundary.  */
7197 +
7198 +void
7199 +s_align_ptwo (int arg)
7200 +{
7201 +  s_align (arg, 0);
7202 +}
7203 +
7204 +/* Switch in and out of alternate macro mode.  */
7205 +
7206 +void
7207 +s_altmacro (int on)
7208 +{
7209 +  demand_empty_rest_of_line ();
7210 +  macro_set_alternate (on);
7211 +}
7212 +
7213 +symbolS *
7214 +s_comm_internal (int param,
7215 +                symbolS *(*comm_parse_extra) (int, symbolS *, addressT))
7216 +{
7217 +  char *name;
7218 +  char c;
7219 +  char *p;
7220 +  offsetT temp, size;
7221 +  symbolS *symbolP = NULL;
7222 +  char *stop = NULL;
7223 +  char stopc;
7224 +  expressionS exp;
7225 +
7226 +  if (flag_mri)
7227 +    stop = mri_comment_field (&stopc);
7228 +
7229 +  name = input_line_pointer;
7230 +  c = get_symbol_end ();
7231 +  /* Just after name is now '\0'.  */
7232 +  p = input_line_pointer;
7233 +  *p = c;
7234 +
7235 +  if (name == p)
7236 +    {
7237 +      as_bad (_("expected symbol name"));
7238 +      ignore_rest_of_line ();
7239 +      goto out;
7240 +    }
7241 +
7242 +  SKIP_WHITESPACE ();
7243 +
7244 +  /* Accept an optional comma after the name.  The comma used to be
7245 +     required, but Irix 5 cc does not generate it for .lcomm.  */
7246 +  if (*input_line_pointer == ',')
7247 +    input_line_pointer++;
7248 +
7249 +  temp = get_absolute_expr (&exp);
7250 +  size = temp;
7251 +#ifdef BFD_ASSEMBLER
7252 +  size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
7253 +#endif
7254 +  if (exp.X_op == O_absent)
7255 +    {
7256 +      as_bad (_("missing size expression"));
7257 +      ignore_rest_of_line ();
7258 +      goto out;
7259 +    }
7260 +  else if (temp != size || !exp.X_unsigned)
7261 +    {
7262 +      as_warn (_("size (%ld) out of range, ignored"), (long) temp);
7263 +      ignore_rest_of_line ();
7264 +      goto out;
7265 +    }
7266 +
7267 +  *p = 0;
7268 +  symbolP = symbol_find_or_make (name);
7269 +  if (S_IS_DEFINED (symbolP) && !S_IS_COMMON (symbolP))
7270 +    {
7271 +      symbolP = NULL;
7272 +      as_bad (_("symbol `%s' is already defined"), name);
7273 +      *p = c;
7274 +      ignore_rest_of_line ();
7275 +      goto out;
7276 +    }
7277 +
7278 +  size = S_GET_VALUE (symbolP);
7279 +  if (size == 0)
7280 +    size = temp;
7281 +  else if (size != temp)
7282 +    as_warn (_("size of \"%s\" is already %ld; not changing to %ld"),
7283 +            name, (long) size, (long) temp);
7284 +
7285 +  *p = c;
7286 +  if (comm_parse_extra != NULL)
7287 +    symbolP = (*comm_parse_extra) (param, symbolP, size);
7288 +  else
7289 +    {
7290 +      S_SET_VALUE (symbolP, (valueT) size);
7291 +      S_SET_EXTERNAL (symbolP);
7292 +#ifdef OBJ_VMS
7293 +      {
7294 +       extern int flag_one;
7295 +       if (size == 0 || !flag_one)
7296 +         S_GET_OTHER (symbolP) = const_flag;
7297 +      }
7298 +#endif
7299 +    }
7300 +
7301 +  demand_empty_rest_of_line ();
7302 + out:
7303 +  if (flag_mri)
7304 +    mri_comment_end (stop, stopc);
7305 +  return symbolP;
7306 +}
7307 +
7308 +void
7309 +s_comm (int ignore)
7310 +{
7311 +  s_comm_internal (ignore, NULL);
7312 +}
7313 +
7314 +/* The MRI COMMON pseudo-op.  We handle this by creating a common
7315 +   symbol with the appropriate name.  We make s_space do the right
7316 +   thing by increasing the size.  */
7317 +
7318 +void
7319 +s_mri_common (int small ATTRIBUTE_UNUSED)
7320 +{
7321 +  char *name;
7322 +  char c;
7323 +  char *alc = NULL;
7324 +  symbolS *sym;
7325 +  offsetT align;
7326 +  char *stop = NULL;
7327 +  char stopc;
7328 +
7329 +  if (!flag_mri)
7330 +    {
7331 +      s_comm (0);
7332 +      return;
7333 +    }
7334 +
7335 +  stop = mri_comment_field (&stopc);
7336 +
7337 +  SKIP_WHITESPACE ();
7338 +
7339 +  name = input_line_pointer;
7340 +  if (!ISDIGIT (*name))
7341 +    c = get_symbol_end ();
7342 +  else
7343 +    {
7344 +      do
7345 +       {
7346 +         ++input_line_pointer;
7347 +       }
7348 +      while (ISDIGIT (*input_line_pointer));
7349 +
7350 +      c = *input_line_pointer;
7351 +      *input_line_pointer = '\0';
7352 +
7353 +      if (line_label != NULL)
7354 +       {
7355 +         alc = (char *) xmalloc (strlen (S_GET_NAME (line_label))
7356 +                                 + (input_line_pointer - name)
7357 +                                 + 1);
7358 +         sprintf (alc, "%s%s", name, S_GET_NAME (line_label));
7359 +         name = alc;
7360 +       }
7361 +    }
7362 +
7363 +  sym = symbol_find_or_make (name);
7364 +  *input_line_pointer = c;
7365 +  if (alc != NULL)
7366 +    free (alc);
7367 +
7368 +  if (*input_line_pointer != ',')
7369 +    align = 0;
7370 +  else
7371 +    {
7372 +      ++input_line_pointer;
7373 +      align = get_absolute_expression ();
7374 +    }
7375 +
7376 +  if (S_IS_DEFINED (sym) && !S_IS_COMMON (sym))
7377 +    {
7378 +      as_bad (_("symbol `%s' is already defined"), S_GET_NAME (sym));
7379 +      ignore_rest_of_line ();
7380 +      mri_comment_end (stop, stopc);
7381 +      return;
7382 +    }
7383 +
7384 +  S_SET_EXTERNAL (sym);
7385 +  mri_common_symbol = sym;
7386 +
7387 +#ifdef S_SET_ALIGN
7388 +  if (align != 0)
7389 +    S_SET_ALIGN (sym, align);
7390 +#endif
7391 +
7392 +  if (line_label != NULL)
7393 +    {
7394 +      expressionS exp;
7395 +      exp.X_op = O_symbol;
7396 +      exp.X_add_symbol = sym;
7397 +      exp.X_add_number = 0;
7398 +      symbol_set_value_expression (line_label, &exp);
7399 +      symbol_set_frag (line_label, &zero_address_frag);
7400 +      S_SET_SEGMENT (line_label, expr_section);
7401 +    }
7402 +
7403 +  /* FIXME: We just ignore the small argument, which distinguishes
7404 +     COMMON and COMMON.S.  I don't know what we can do about it.  */
7405 +
7406 +  /* Ignore the type and hptype.  */
7407 +  if (*input_line_pointer == ',')
7408 +    input_line_pointer += 2;
7409 +  if (*input_line_pointer == ',')
7410 +    input_line_pointer += 2;
7411 +
7412 +  demand_empty_rest_of_line ();
7413 +
7414 +  mri_comment_end (stop, stopc);
7415 +}
7416 +
7417 +void
7418 +s_data (int ignore ATTRIBUTE_UNUSED)
7419 +{
7420 +  segT section;
7421 +  register int temp;
7422 +
7423 +  temp = get_absolute_expression ();
7424 +  if (flag_readonly_data_in_text)
7425 +    {
7426 +      section = text_section;
7427 +      temp += 1000;
7428 +    }
7429 +  else
7430 +    section = data_section;
7431 +
7432 +  subseg_set (section, (subsegT) temp);
7433 +
7434 +#ifdef OBJ_VMS
7435 +  const_flag = 0;
7436 +#endif
7437 +  demand_empty_rest_of_line ();
7438 +}
7439 +
7440 +/* Handle the .appfile pseudo-op.  This is automatically generated by
7441 +   do_scrub_chars when a preprocessor # line comment is seen with a
7442 +   file name.  This default definition may be overridden by the object
7443 +   or CPU specific pseudo-ops.  This function is also the default
7444 +   definition for .file; the APPFILE argument is 1 for .appfile, 0 for
7445 +   .file.  */
7446 +
7447 +void
7448 +s_app_file_string (char *file, int appfile ATTRIBUTE_UNUSED)
7449 +{
7450 +#ifdef LISTING
7451 +  if (listing)
7452 +    listing_source_file (file);
7453 +#endif
7454 +  register_dependency (file);
7455 +#ifdef obj_app_file
7456 +  obj_app_file (file, appfile);
7457 +#endif
7458 +}
7459 +
7460 +void
7461 +s_app_file (int appfile)
7462 +{
7463 +  register char *s;
7464 +  int length;
7465 +
7466 +  /* Some assemblers tolerate immediately following '"'.  */
7467 +  if ((s = demand_copy_string (&length)) != 0)
7468 +    {
7469 +      /* If this is a fake .appfile, a fake newline was inserted into
7470 +        the buffer.  Passing -2 to new_logical_line tells it to
7471 +        account for it.  */
7472 +      int may_omit
7473 +       = (!new_logical_line (s, appfile ? -2 : -1) && appfile);
7474 +
7475 +      /* In MRI mode, the preprocessor may have inserted an extraneous
7476 +        backquote.  */
7477 +      if (flag_m68k_mri
7478 +         && *input_line_pointer == '\''
7479 +         && is_end_of_line[(unsigned char) input_line_pointer[1]])
7480 +       ++input_line_pointer;
7481 +
7482 +      demand_empty_rest_of_line ();
7483 +      if (!may_omit)
7484 +       s_app_file_string (s, appfile);
7485 +    }
7486 +}
7487 +
7488 +/* Handle the .appline pseudo-op.  This is automatically generated by
7489 +   do_scrub_chars when a preprocessor # line comment is seen.  This
7490 +   default definition may be overridden by the object or CPU specific
7491 +   pseudo-ops.  */
7492 +
7493 +void
7494 +s_app_line (int ignore ATTRIBUTE_UNUSED)
7495 +{
7496 +  int l;
7497 +
7498 +  /* The given number is that of the next line.  */
7499 +  l = get_absolute_expression () - 1;
7500 +  if (l < 0)
7501 +    /* Some of the back ends can't deal with non-positive line numbers.
7502 +       Besides, it's silly.  */
7503 +    as_warn (_("line numbers must be positive; line number %d rejected"),
7504 +            l + 1);
7505 +  else
7506 +    {
7507 +      new_logical_line ((char *) NULL, l);
7508 +#ifdef LISTING
7509 +      if (listing)
7510 +       listing_source_line (l);
7511 +#endif
7512 +    }
7513 +  demand_empty_rest_of_line ();
7514 +}
7515 +
7516 +/* Handle the .end pseudo-op.  Actually, the real work is done in
7517 +   read_a_source_file.  */
7518 +
7519 +void
7520 +s_end (int ignore ATTRIBUTE_UNUSED)
7521 +{
7522 +  if (flag_mri)
7523 +    {
7524 +      /* The MRI assembler permits the start symbol to follow .end,
7525 +        but we don't support that.  */
7526 +      SKIP_WHITESPACE ();
7527 +      if (!is_end_of_line[(unsigned char) *input_line_pointer]
7528 +         && *input_line_pointer != '*'
7529 +         && *input_line_pointer != '!')
7530 +       as_warn (_("start address not supported"));
7531 +    }
7532 +}
7533 +
7534 +/* Handle the .err pseudo-op.  */
7535 +
7536 +void
7537 +s_err (int ignore ATTRIBUTE_UNUSED)
7538 +{
7539 +  as_bad (_(".err encountered"));
7540 +  demand_empty_rest_of_line ();
7541 +}
7542 +
7543 +/* Handle the .error and .warning pseudo-ops.  */
7544 +
7545 +void
7546 +s_errwarn (int err)
7547 +{
7548 +  int len;
7549 +  /* The purpose for the conditional assignment is not to
7550 +     internationalize the directive itself, but that we need a
7551 +     self-contained message, one that can be passed like the
7552 +     demand_copy_C_string return value, and with no assumption on the
7553 +     location of the name of the directive within the message.  */
7554 +  char *msg
7555 +    = (err ? _(".error directive invoked in source file")
7556 +       : _(".warning directive invoked in source file"));
7557 +
7558 +  if (!is_it_end_of_statement ())
7559 +    {
7560 +      if (*input_line_pointer != '\"')
7561 +       {
7562 +         as_bad (_("%s argument must be a string"),
7563 +                 err ? ".error" : ".warning");
7564 +         ignore_rest_of_line ();
7565 +         return;
7566 +       }
7567 +
7568 +      msg = demand_copy_C_string (&len);
7569 +      if (msg == NULL)
7570 +       return;
7571 +    }
7572 +
7573 +  if (err)
7574 +    as_bad ("%s", msg);
7575 +  else
7576 +    as_warn ("%s", msg);
7577 +  demand_empty_rest_of_line ();
7578 +}
7579 +
7580 +/* Handle the MRI fail pseudo-op.  */
7581 +
7582 +void
7583 +s_fail (int ignore ATTRIBUTE_UNUSED)
7584 +{
7585 +  offsetT temp;
7586 +  char *stop = NULL;
7587 +  char stopc;
7588 +
7589 +  if (flag_mri)
7590 +    stop = mri_comment_field (&stopc);
7591 +
7592 +  temp = get_absolute_expression ();
7593 +  if (temp >= 500)
7594 +    as_warn (_(".fail %ld encountered"), (long) temp);
7595 +  else
7596 +    as_bad (_(".fail %ld encountered"), (long) temp);
7597 +
7598 +  demand_empty_rest_of_line ();
7599 +
7600 +  if (flag_mri)
7601 +    mri_comment_end (stop, stopc);
7602 +}
7603 +
7604 +void
7605 +s_fill (int ignore ATTRIBUTE_UNUSED)
7606 +{
7607 +  expressionS rep_exp;
7608 +  long size = 1;
7609 +  register long fill = 0;
7610 +  char *p;
7611 +
7612 +#ifdef md_flush_pending_output
7613 +  md_flush_pending_output ();
7614 +#endif
7615 +
7616 +  get_known_segmented_expression (&rep_exp);
7617 +  if (*input_line_pointer == ',')
7618 +    {
7619 +      input_line_pointer++;
7620 +      size = get_absolute_expression ();
7621 +      if (*input_line_pointer == ',')
7622 +       {
7623 +         input_line_pointer++;
7624 +         fill = get_absolute_expression ();
7625 +       }
7626 +    }
7627 +
7628 +  /* This is to be compatible with BSD 4.2 AS, not for any rational reason.  */
7629 +#define BSD_FILL_SIZE_CROCK_8 (8)
7630 +  if (size > BSD_FILL_SIZE_CROCK_8)
7631 +    {
7632 +      as_warn (_(".fill size clamped to %d"), BSD_FILL_SIZE_CROCK_8);
7633 +      size = BSD_FILL_SIZE_CROCK_8;
7634 +    }
7635 +  if (size < 0)
7636 +    {
7637 +      as_warn (_("size negative; .fill ignored"));
7638 +      size = 0;
7639 +    }
7640 +  else if (rep_exp.X_op == O_constant && rep_exp.X_add_number <= 0)
7641 +    {
7642 +      if (rep_exp.X_add_number < 0)
7643 +       as_warn (_("repeat < 0; .fill ignored"));
7644 +      size = 0;
7645 +    }
7646 +
7647 +  if (size && !need_pass_2)
7648 +    {
7649 +      if (rep_exp.X_op == O_constant)
7650 +       {
7651 +         p = frag_var (rs_fill, (int) size, (int) size,
7652 +                       (relax_substateT) 0, (symbolS *) 0,
7653 +                       (offsetT) rep_exp.X_add_number,
7654 +                       (char *) 0);
7655 +       }
7656 +      else
7657 +       {
7658 +         /* We don't have a constant repeat count, so we can't use
7659 +            rs_fill.  We can get the same results out of rs_space,
7660 +            but its argument is in bytes, so we must multiply the
7661 +            repeat count by size.  */
7662 +
7663 +         symbolS *rep_sym;
7664 +         rep_sym = make_expr_symbol (&rep_exp);
7665 +         if (size != 1)
7666 +           {
7667 +             expressionS size_exp;
7668 +             size_exp.X_op = O_constant;
7669 +             size_exp.X_add_number = size;
7670 +
7671 +             rep_exp.X_op = O_multiply;
7672 +             rep_exp.X_add_symbol = rep_sym;
7673 +             rep_exp.X_op_symbol = make_expr_symbol (&size_exp);
7674 +             rep_exp.X_add_number = 0;
7675 +             rep_sym = make_expr_symbol (&rep_exp);
7676 +           }
7677 +
7678 +         p = frag_var (rs_space, (int) size, (int) size,
7679 +                       (relax_substateT) 0, rep_sym, (offsetT) 0, (char *) 0);
7680 +       }
7681 +
7682 +      memset (p, 0, (unsigned int) size);
7683 +
7684 +      /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
7685 +        flavoured AS.  The following bizarre behaviour is to be
7686 +        compatible with above.  I guess they tried to take up to 8
7687 +        bytes from a 4-byte expression and they forgot to sign
7688 +        extend.  */
7689 +#define BSD_FILL_SIZE_CROCK_4 (4)
7690 +      md_number_to_chars (p, (valueT) fill,
7691 +                         (size > BSD_FILL_SIZE_CROCK_4
7692 +                          ? BSD_FILL_SIZE_CROCK_4
7693 +                          : (int) size));
7694 +      /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
7695 +        but emits no error message because it seems a legal thing to do.
7696 +        It is a degenerate case of .fill but could be emitted by a
7697 +        compiler.  */
7698 +    }
7699 +  demand_empty_rest_of_line ();
7700 +}
7701 +
7702 +void
7703 +s_globl (int ignore ATTRIBUTE_UNUSED)
7704 +{
7705 +  char *name;
7706 +  int c;
7707 +  symbolS *symbolP;
7708 +  char *stop = NULL;
7709 +  char stopc;
7710 +
7711 +  if (flag_mri)
7712 +    stop = mri_comment_field (&stopc);
7713 +
7714 +  do
7715 +    {
7716 +      name = input_line_pointer;
7717 +      c = get_symbol_end ();
7718 +      symbolP = symbol_find_or_make (name);
7719 +      S_SET_EXTERNAL (symbolP);
7720 +
7721 +      *input_line_pointer = c;
7722 +      SKIP_WHITESPACE ();
7723 +      c = *input_line_pointer;
7724 +      if (c == ',')
7725 +       {
7726 +         input_line_pointer++;
7727 +         SKIP_WHITESPACE ();
7728 +         if (is_end_of_line[(unsigned char) *input_line_pointer])
7729 +           c = '\n';
7730 +       }
7731 +    }
7732 +  while (c == ',');
7733 +
7734 +  demand_empty_rest_of_line ();
7735 +
7736 +  if (flag_mri)
7737 +    mri_comment_end (stop, stopc);
7738 +}
7739 +
7740 +/* Handle the MRI IRP and IRPC pseudo-ops.  */
7741 +
7742 +void
7743 +s_irp (int irpc)
7744 +{
7745 +  char *file, *eol;
7746 +  unsigned int line;
7747 +  sb s;
7748 +  const char *err;
7749 +  sb out;
7750 +
7751 +  as_where (&file, &line);
7752 +
7753 +  sb_new (&s);
7754 +  eol = find_end_of_line (input_line_pointer, 0);
7755 +  sb_add_buffer (&s, input_line_pointer, eol - input_line_pointer);
7756 +  input_line_pointer = eol;
7757 +
7758 +  sb_new (&out);
7759 +
7760 +  err = expand_irp (irpc, 0, &s, &out, get_line_sb);
7761 +  if (err != NULL)
7762 +    as_bad_where (file, line, "%s", err);
7763 +
7764 +  sb_kill (&s);
7765 +
7766 +  input_scrub_include_sb (&out, input_line_pointer, 1);
7767 +  sb_kill (&out);
7768 +  buffer_limit = input_scrub_next_buffer (&input_line_pointer);
7769 +}
7770 +
7771 +/* Handle the .linkonce pseudo-op.  This tells the assembler to mark
7772 +   the section to only be linked once.  However, this is not supported
7773 +   by most object file formats.  This takes an optional argument,
7774 +   which is what to do about duplicates.  */
7775 +
7776 +void
7777 +s_linkonce (int ignore ATTRIBUTE_UNUSED)
7778 +{
7779 +  enum linkonce_type type;
7780 +
7781 +  SKIP_WHITESPACE ();
7782 +
7783 +  type = LINKONCE_DISCARD;
7784 +
7785 +  if (!is_end_of_line[(unsigned char) *input_line_pointer])
7786 +    {
7787 +      char *s;
7788 +      char c;
7789 +
7790 +      s = input_line_pointer;
7791 +      c = get_symbol_end ();
7792 +      if (strcasecmp (s, "discard") == 0)
7793 +       type = LINKONCE_DISCARD;
7794 +      else if (strcasecmp (s, "one_only") == 0)
7795 +       type = LINKONCE_ONE_ONLY;
7796 +      else if (strcasecmp (s, "same_size") == 0)
7797 +       type = LINKONCE_SAME_SIZE;
7798 +      else if (strcasecmp (s, "same_contents") == 0)
7799 +       type = LINKONCE_SAME_CONTENTS;
7800 +      else
7801 +       as_warn (_("unrecognized .linkonce type `%s'"), s);
7802 +
7803 +      *input_line_pointer = c;
7804 +    }
7805 +
7806 +#ifdef obj_handle_link_once
7807 +  obj_handle_link_once (type);
7808 +#else /* ! defined (obj_handle_link_once) */
7809 +#ifdef BFD_ASSEMBLER
7810 +  {
7811 +    flagword flags;
7812 +
7813 +    if ((bfd_applicable_section_flags (stdoutput) & SEC_LINK_ONCE) == 0)
7814 +      as_warn (_(".linkonce is not supported for this object file format"));
7815 +
7816 +    flags = bfd_get_section_flags (stdoutput, now_seg);
7817 +    flags |= SEC_LINK_ONCE;
7818 +    switch (type)
7819 +      {
7820 +      default:
7821 +       abort ();
7822 +      case LINKONCE_DISCARD:
7823 +       flags |= SEC_LINK_DUPLICATES_DISCARD;
7824 +       break;
7825 +      case LINKONCE_ONE_ONLY:
7826 +       flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
7827 +       break;
7828 +      case LINKONCE_SAME_SIZE:
7829 +       flags |= SEC_LINK_DUPLICATES_SAME_SIZE;
7830 +       break;
7831 +      case LINKONCE_SAME_CONTENTS:
7832 +       flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
7833 +       break;
7834 +      }
7835 +    if (!bfd_set_section_flags (stdoutput, now_seg, flags))
7836 +      as_bad (_("bfd_set_section_flags: %s"),
7837 +             bfd_errmsg (bfd_get_error ()));
7838 +  }
7839 +#else /* ! defined (BFD_ASSEMBLER) */
7840 +  as_warn (_(".linkonce is not supported for this object file format"));
7841 +#endif /* ! defined (BFD_ASSEMBLER) */
7842 +#endif /* ! defined (obj_handle_link_once) */
7843 +
7844 +  demand_empty_rest_of_line ();
7845 +}
7846 +
7847 +void
7848 +bss_alloc (symbolS *symbolP, addressT size, int align)
7849 +{
7850 +  char *pfrag;
7851 +  segT current_seg = now_seg;
7852 +  subsegT current_subseg = now_subseg;
7853 +  segT bss_seg = bss_section;
7854 +
7855 +#if defined (TC_MIPS) || defined (TC_ALPHA)
7856 +  if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour
7857 +      || OUTPUT_FLAVOR == bfd_target_elf_flavour)
7858 +    {
7859 +      /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss.  */
7860 +      if (size <= bfd_get_gp_size (stdoutput))
7861 +       {
7862 +         bss_seg = subseg_new (".sbss", 1);
7863 +         seg_info (bss_seg)->bss = 1;
7864 +#ifdef BFD_ASSEMBLER
7865 +         if (!bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC))
7866 +           as_warn (_("error setting flags for \".sbss\": %s"),
7867 +                    bfd_errmsg (bfd_get_error ()));
7868 +#endif
7869 +       }
7870 +    }
7871 +#endif
7872 +  subseg_set (bss_seg, 1);
7873 +
7874 +  if (align)
7875 +    {
7876 +      record_alignment (bss_seg, align);
7877 +      frag_align (align, 0, 0);
7878 +    }
7879 +
7880 +  /* Detach from old frag.  */
7881 +  if (S_GET_SEGMENT (symbolP) == bss_seg)
7882 +    symbol_get_frag (symbolP)->fr_symbol = NULL;
7883 +
7884 +  symbol_set_frag (symbolP, frag_now);
7885 +  pfrag = frag_var (rs_org, 1, 1, 0, symbolP, size, NULL);
7886 +  *pfrag = 0;
7887 +
7888 +#ifdef S_SET_SIZE
7889 +  S_SET_SIZE (symbolP, size);
7890 +#endif
7891 +  S_SET_SEGMENT (symbolP, bss_seg);
7892 +
7893 +#ifdef OBJ_COFF
7894 +  /* The symbol may already have been created with a preceding
7895 +     ".globl" directive -- be careful not to step on storage class
7896 +     in that case.  Otherwise, set it to static.  */
7897 +  if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
7898 +    S_SET_STORAGE_CLASS (symbolP, C_STAT);
7899 +#endif /* OBJ_COFF */
7900 +
7901 +  subseg_set (current_seg, current_subseg);
7902 +}
7903 +
7904 +offsetT
7905 +parse_align (int align_bytes)
7906 +{
7907 +  expressionS exp;
7908 +  addressT align;
7909 +
7910 +  SKIP_WHITESPACE ();
7911 +  if (*input_line_pointer != ',')
7912 +    {
7913 +    no_align:
7914 +      as_bad (_("expected alignment after size"));
7915 +      ignore_rest_of_line ();
7916 +      return -1;
7917 +    }
7918 +
7919 +  input_line_pointer++;
7920 +  SKIP_WHITESPACE ();
7921 +
7922 +  align = get_absolute_expr (&exp);
7923 +  if (exp.X_op == O_absent)
7924 +    goto no_align;
7925 +
7926 +  if (!exp.X_unsigned)
7927 +    {
7928 +      as_warn (_("alignment negative; 0 assumed"));
7929 +      align = 0;
7930 +    }
7931 +
7932 +  if (align_bytes && align != 0)
7933 +    {
7934 +      /* convert to a power of 2 alignment */
7935 +      unsigned int alignp2 = 0;
7936 +      while ((align & 1) == 0)
7937 +       align >>= 1, ++alignp2;
7938 +      if (align != 1)
7939 +       {
7940 +         as_bad (_("alignment not a power of 2"));
7941 +         ignore_rest_of_line ();
7942 +         return -1;
7943 +       }
7944 +      align = alignp2;
7945 +    }
7946 +  return align;
7947 +}
7948 +
7949 +/* Called from s_comm_internal after symbol name and size have been
7950 +   parsed.  NEEDS_ALIGN is 0 if it was an ".lcomm" (2 args only),
7951 +   1 if this was a ".bss" directive which has a 3rd argument
7952 +   (alignment as a power of 2), or 2 if this was a ".bss" directive
7953 +   with alignment in bytes.  */
7954 +
7955 +symbolS *
7956 +s_lcomm_internal (int needs_align, symbolS *symbolP, addressT size)
7957 +{
7958 +  addressT align = 0;
7959 +
7960 +  if (needs_align)
7961 +    {
7962 +      align = parse_align (needs_align - 1);
7963 +      if (align == (addressT) -1)
7964 +       return NULL;
7965 +    }
7966 +  else
7967 +    /* Assume some objects may require alignment on some systems.  */
7968 +    TC_IMPLICIT_LCOMM_ALIGNMENT (size, align);
7969 +
7970 +  bss_alloc (symbolP, size, align);
7971 +  return symbolP;
7972 +}
7973 +
7974 +void
7975 +s_lcomm (int needs_align)
7976 +{
7977 +  s_comm_internal (needs_align, s_lcomm_internal);
7978 +}
7979 +
7980 +void
7981 +s_lcomm_bytes (int needs_align)
7982 +{
7983 +  s_comm_internal (needs_align * 2, s_lcomm_internal);
7984 +}
7985 +
7986 +void
7987 +s_lsym (int ignore ATTRIBUTE_UNUSED)
7988 +{
7989 +  register char *name;
7990 +  register char c;
7991 +  register char *p;
7992 +  expressionS exp;
7993 +  register symbolS *symbolP;
7994 +
7995 +  /* We permit ANY defined expression: BSD4.2 demands constants.  */
7996 +  name = input_line_pointer;
7997 +  c = get_symbol_end ();
7998 +  p = input_line_pointer;
7999 +  *p = c;
8000 +
8001 +  if (name == p)
8002 +    {
8003 +      as_bad (_("expected symbol name"));
8004 +      ignore_rest_of_line ();
8005 +      return;
8006 +    }
8007 +
8008 +  SKIP_WHITESPACE ();
8009 +
8010 +  if (*input_line_pointer != ',')
8011 +    {
8012 +      *p = 0;
8013 +      as_bad (_("expected comma after \"%s\""), name);
8014 +      *p = c;
8015 +      ignore_rest_of_line ();
8016 +      return;
8017 +    }
8018 +
8019 +  input_line_pointer++;
8020 +  expression (&exp);
8021 +
8022 +  if (exp.X_op != O_constant
8023 +      && exp.X_op != O_register)
8024 +    {
8025 +      as_bad (_("bad expression"));
8026 +      ignore_rest_of_line ();
8027 +      return;
8028 +    }
8029 +
8030 +  *p = 0;
8031 +  symbolP = symbol_find_or_make (name);
8032 +
8033 +  /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0 &&
8034 +     symbolP->sy_desc == 0) out of this test because coff doesn't have
8035 +     those fields, and I can't see when they'd ever be tripped.  I
8036 +     don't think I understand why they were here so I may have
8037 +     introduced a bug. As recently as 1.37 didn't have this test
8038 +     anyway.  xoxorich.  */
8039 +
8040 +  if (S_GET_SEGMENT (symbolP) == undefined_section
8041 +      && S_GET_VALUE (symbolP) == 0)
8042 +    {
8043 +      /* The name might be an undefined .global symbol; be sure to
8044 +        keep the "external" bit.  */
8045 +      S_SET_SEGMENT (symbolP,
8046 +                    (exp.X_op == O_constant
8047 +                     ? absolute_section
8048 +                     : reg_section));
8049 +      S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
8050 +    }
8051 +  else
8052 +    {
8053 +      as_bad (_("symbol `%s' is already defined"), name);
8054 +    }
8055 +
8056 +  *p = c;
8057 +  demand_empty_rest_of_line ();
8058 +}
8059 +
8060 +/* Read a line into an sb.  Returns the character that ended the line
8061 +   or zero if there are no more lines.  */
8062 +
8063 +static int
8064 +get_line_sb (sb *line)
8065 +{
8066 +  char *eol;
8067 +
8068 +  if (input_line_pointer[-1] == '\n')
8069 +    bump_line_counters ();
8070 +
8071 +  if (input_line_pointer >= buffer_limit)
8072 +    {
8073 +      buffer_limit = input_scrub_next_buffer (&input_line_pointer);
8074 +      if (buffer_limit == 0)
8075 +       return 0;
8076 +    }
8077 +
8078 +  eol = find_end_of_line (input_line_pointer, flag_m68k_mri);
8079 +  sb_add_buffer (line, input_line_pointer, eol - input_line_pointer);
8080 +  input_line_pointer = eol;
8081 +
8082 +  /* Don't skip multiple end-of-line characters, because that breaks support
8083 +     for the IA-64 stop bit (;;) which looks like two consecutive end-of-line
8084 +     characters but isn't.  Instead just skip one end of line character and
8085 +     return the character skipped so that the caller can re-insert it if
8086 +     necessary.   */
8087 +  return *input_line_pointer++;
8088 +}
8089 +
8090 +/* Define a macro.  This is an interface to macro.c.  */
8091 +
8092 +void
8093 +s_macro (int ignore ATTRIBUTE_UNUSED)
8094 +{
8095 +  char *file, *eol;
8096 +  unsigned int line;
8097 +  sb s;
8098 +  const char *err;
8099 +  const char *name;
8100 +
8101 +  as_where (&file, &line);
8102 +
8103 +  sb_new (&s);
8104 +  eol = find_end_of_line (input_line_pointer, 0);
8105 +  sb_add_buffer (&s, input_line_pointer, eol - input_line_pointer);
8106 +  input_line_pointer = eol;
8107 +
8108 +  if (line_label != NULL)
8109 +    {
8110 +      sb label;
8111 +
8112 +      sb_new (&label);
8113 +      sb_add_string (&label, S_GET_NAME (line_label));
8114 +      err = define_macro (0, &s, &label, get_line_sb, file, line, &name);
8115 +      sb_kill (&label);
8116 +    }
8117 +  else
8118 +    err = define_macro (0, &s, NULL, get_line_sb, file, line, &name);
8119 +  if (err != NULL)
8120 +    as_bad_where (file, line, err, name);
8121 +  else
8122 +    {
8123 +      if (line_label != NULL)
8124 +       {
8125 +         S_SET_SEGMENT (line_label, absolute_section);
8126 +         S_SET_VALUE (line_label, 0);
8127 +         symbol_set_frag (line_label, &zero_address_frag);
8128 +       }
8129 +
8130 +      if (((NO_PSEUDO_DOT || flag_m68k_mri)
8131 +          && hash_find (po_hash, name) != NULL)
8132 +         || (!flag_m68k_mri
8133 +             && *name == '.'
8134 +             && hash_find (po_hash, name + 1) != NULL))
8135 +       as_warn_where (file,
8136 +                line,
8137 +                _("attempt to redefine pseudo-op `%s' ignored"),
8138 +                name);
8139 +    }
8140 +
8141 +  sb_kill (&s);
8142 +}
8143 +
8144 +/* Handle the .mexit pseudo-op, which immediately exits a macro
8145 +   expansion.  */
8146 +
8147 +void
8148 +s_mexit (int ignore ATTRIBUTE_UNUSED)
8149 +{
8150 +  cond_exit_macro (macro_nest);
8151 +  buffer_limit = input_scrub_next_buffer (&input_line_pointer);
8152 +}
8153 +
8154 +/* Switch in and out of MRI mode.  */
8155 +
8156 +void
8157 +s_mri (int ignore ATTRIBUTE_UNUSED)
8158 +{
8159 +  int on, old_flag;
8160 +
8161 +  on = get_absolute_expression ();
8162 +  old_flag = flag_mri;
8163 +  if (on != 0)
8164 +    {
8165 +      flag_mri = 1;
8166 +#ifdef TC_M68K
8167 +      flag_m68k_mri = 1;
8168 +#endif
8169 +      macro_mri_mode (1);
8170 +    }
8171 +  else
8172 +    {
8173 +      flag_mri = 0;
8174 +#ifdef TC_M68K
8175 +      flag_m68k_mri = 0;
8176 +#endif
8177 +      macro_mri_mode (0);
8178 +    }
8179 +
8180 +  /* Operator precedence changes in m68k MRI mode, so we need to
8181 +     update the operator rankings.  */
8182 +  expr_set_precedence ();
8183 +
8184 +#ifdef MRI_MODE_CHANGE
8185 +  if (on != old_flag)
8186 +    MRI_MODE_CHANGE (on);
8187 +#endif
8188 +
8189 +  demand_empty_rest_of_line ();
8190 +}
8191 +
8192 +/* Handle changing the location counter.  */
8193 +
8194 +static void
8195 +do_org (segT segment, expressionS *exp, int fill)
8196 +{
8197 +  if (segment != now_seg && segment != absolute_section)
8198 +    as_bad (_("invalid segment \"%s\""), segment_name (segment));
8199 +
8200 +  if (now_seg == absolute_section)
8201 +    {
8202 +      if (fill != 0)
8203 +       as_warn (_("ignoring fill value in absolute section"));
8204 +      if (exp->X_op != O_constant)
8205 +       {
8206 +         as_bad (_("only constant offsets supported in absolute section"));
8207 +         exp->X_add_number = 0;
8208 +       }
8209 +      abs_section_offset = exp->X_add_number;
8210 +    }
8211 +  else
8212 +    {
8213 +      char *p;
8214 +      symbolS *sym = exp->X_add_symbol;
8215 +      offsetT off = exp->X_add_number * OCTETS_PER_BYTE;
8216 +
8217 +      if (exp->X_op != O_constant && exp->X_op != O_symbol)
8218 +       {
8219 +         /* Handle complex expressions.  */
8220 +         sym = make_expr_symbol (exp);
8221 +         off = 0;
8222 +       }
8223 +
8224 +      p = frag_var (rs_org, 1, 1, (relax_substateT) 0, sym, off, (char *) 0);
8225 +      *p = fill;
8226 +    }
8227 +}
8228 +
8229 +void
8230 +s_org (int ignore ATTRIBUTE_UNUSED)
8231 +{
8232 +  register segT segment;
8233 +  expressionS exp;
8234 +  register long temp_fill;
8235 +
8236 +#ifdef md_flush_pending_output
8237 +  md_flush_pending_output ();
8238 +#endif
8239 +
8240 +  /* The m68k MRI assembler has a different meaning for .org.  It
8241 +     means to create an absolute section at a given address.  We can't
8242 +     support that--use a linker script instead.  */
8243 +  if (flag_m68k_mri)
8244 +    {
8245 +      as_bad (_("MRI style ORG pseudo-op not supported"));
8246 +      ignore_rest_of_line ();
8247 +      return;
8248 +    }
8249 +
8250 +  /* Don't believe the documentation of BSD 4.2 AS.  There is no such
8251 +     thing as a sub-segment-relative origin.  Any absolute origin is
8252 +     given a warning, then assumed to be segment-relative.  Any
8253 +     segmented origin expression ("foo+42") had better be in the right
8254 +     segment or the .org is ignored.
8255 +
8256 +     BSD 4.2 AS warns if you try to .org backwards. We cannot because
8257 +     we never know sub-segment sizes when we are reading code.  BSD
8258 +     will crash trying to emit negative numbers of filler bytes in
8259 +     certain .orgs. We don't crash, but see as-write for that code.
8260 +
8261 +     Don't make frag if need_pass_2==1.  */
8262 +  segment = get_known_segmented_expression (&exp);
8263 +  if (*input_line_pointer == ',')
8264 +    {
8265 +      input_line_pointer++;
8266 +      temp_fill = get_absolute_expression ();
8267 +    }
8268 +  else
8269 +    temp_fill = 0;
8270 +
8271 +  if (!need_pass_2)
8272 +    do_org (segment, &exp, temp_fill);
8273 +
8274 +  demand_empty_rest_of_line ();
8275 +}
8276 +
8277 +/* Handle parsing for the MRI SECT/SECTION pseudo-op.  This should be
8278 +   called by the obj-format routine which handles section changing
8279 +   when in MRI mode.  It will create a new section, and return it.  It
8280 +   will set *TYPE to the section type: one of 'C' (code), 'D' (data),
8281 +   'M' (mixed), or 'R' (romable).  If BFD_ASSEMBLER is defined, the
8282 +   flags will be set in the section.  */
8283 +
8284 +void
8285 +s_mri_sect (char *type ATTRIBUTE_UNUSED)
8286 +{
8287 +#ifdef TC_M68K
8288 +
8289 +  char *name;
8290 +  char c;
8291 +  segT seg;
8292 +
8293 +  SKIP_WHITESPACE ();
8294 +
8295 +  name = input_line_pointer;
8296 +  if (!ISDIGIT (*name))
8297 +    c = get_symbol_end ();
8298 +  else
8299 +    {
8300 +      do
8301 +       {
8302 +         ++input_line_pointer;
8303 +       }
8304 +      while (ISDIGIT (*input_line_pointer));
8305 +
8306 +      c = *input_line_pointer;
8307 +      *input_line_pointer = '\0';
8308 +    }
8309 +
8310 +  name = xstrdup (name);
8311 +
8312 +  *input_line_pointer = c;
8313 +
8314 +  seg = subseg_new (name, 0);
8315 +
8316 +  if (*input_line_pointer == ',')
8317 +    {
8318 +      int align;
8319 +
8320 +      ++input_line_pointer;
8321 +      align = get_absolute_expression ();
8322 +      record_alignment (seg, align);
8323 +    }
8324 +
8325 +  *type = 'C';
8326 +  if (*input_line_pointer == ',')
8327 +    {
8328 +      c = *++input_line_pointer;
8329 +      c = TOUPPER (c);
8330 +      if (c == 'C' || c == 'D' || c == 'M' || c == 'R')
8331 +       *type = c;
8332 +      else
8333 +       as_bad (_("unrecognized section type"));
8334 +      ++input_line_pointer;
8335 +
8336 +#ifdef BFD_ASSEMBLER
8337 +      {
8338 +       flagword flags;
8339 +
8340 +       flags = SEC_NO_FLAGS;
8341 +       if (*type == 'C')
8342 +         flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE;
8343 +       else if (*type == 'D' || *type == 'M')
8344 +         flags = SEC_ALLOC | SEC_LOAD | SEC_DATA;
8345 +       else if (*type == 'R')
8346 +         flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY | SEC_ROM;
8347 +       if (flags != SEC_NO_FLAGS)
8348 +         {
8349 +           if (!bfd_set_section_flags (stdoutput, seg, flags))
8350 +             as_warn (_("error setting flags for \"%s\": %s"),
8351 +                      bfd_section_name (stdoutput, seg),
8352 +                      bfd_errmsg (bfd_get_error ()));
8353 +         }
8354 +      }
8355 +#endif
8356 +    }
8357 +
8358 +  /* Ignore the HP type.  */
8359 +  if (*input_line_pointer == ',')
8360 +    input_line_pointer += 2;
8361 +
8362 +  demand_empty_rest_of_line ();
8363 +
8364 +#else /* ! TC_M68K */
8365 +#ifdef TC_I960
8366 +
8367 +  char *name;
8368 +  char c;
8369 +  segT seg;
8370 +
8371 +  SKIP_WHITESPACE ();
8372 +
8373 +  name = input_line_pointer;
8374 +  c = get_symbol_end ();
8375 +
8376 +  name = xstrdup (name);
8377 +
8378 +  *input_line_pointer = c;
8379 +
8380 +  seg = subseg_new (name, 0);
8381 +
8382 +  if (*input_line_pointer != ',')
8383 +    *type = 'C';
8384 +  else
8385 +    {
8386 +      char *sectype;
8387 +
8388 +      ++input_line_pointer;
8389 +      SKIP_WHITESPACE ();
8390 +      sectype = input_line_pointer;
8391 +      c = get_symbol_end ();
8392 +      if (*sectype == '\0')
8393 +       *type = 'C';
8394 +      else if (strcasecmp (sectype, "text") == 0)
8395 +       *type = 'C';
8396 +      else if (strcasecmp (sectype, "data") == 0)
8397 +       *type = 'D';
8398 +      else if (strcasecmp (sectype, "romdata") == 0)
8399 +       *type = 'R';
8400 +      else
8401 +       as_warn (_("unrecognized section type `%s'"), sectype);
8402 +      *input_line_pointer = c;
8403 +    }
8404 +
8405 +  if (*input_line_pointer == ',')
8406 +    {
8407 +      char *seccmd;
8408 +
8409 +      ++input_line_pointer;
8410 +      SKIP_WHITESPACE ();
8411 +      seccmd = input_line_pointer;
8412 +      c = get_symbol_end ();
8413 +      if (strcasecmp (seccmd, "absolute") == 0)
8414 +       {
8415 +         as_bad (_("absolute sections are not supported"));
8416 +         *input_line_pointer = c;
8417 +         ignore_rest_of_line ();
8418 +         return;
8419 +       }
8420 +      else if (strcasecmp (seccmd, "align") == 0)
8421 +       {
8422 +         int align;
8423 +
8424 +         *input_line_pointer = c;
8425 +         align = get_absolute_expression ();
8426 +         record_alignment (seg, align);
8427 +       }
8428 +      else
8429 +       {
8430 +         as_warn (_("unrecognized section command `%s'"), seccmd);
8431 +         *input_line_pointer = c;
8432 +       }
8433 +    }
8434 +
8435 +  demand_empty_rest_of_line ();
8436 +
8437 +#else /* ! TC_I960 */
8438 +  /* The MRI assembler seems to use different forms of .sect for
8439 +     different targets.  */
8440 +  as_bad ("MRI mode not supported for this target");
8441 +  ignore_rest_of_line ();
8442 +#endif /* ! TC_I960 */
8443 +#endif /* ! TC_M68K */
8444 +}
8445 +
8446 +/* Handle the .print pseudo-op.  */
8447 +
8448 +void
8449 +s_print (int ignore ATTRIBUTE_UNUSED)
8450 +{
8451 +  char *s;
8452 +  int len;
8453 +
8454 +  s = demand_copy_C_string (&len);
8455 +  if (s != NULL)
8456 +    printf ("%s\n", s);
8457 +  demand_empty_rest_of_line ();
8458 +}
8459 +
8460 +/* Handle the .purgem pseudo-op.  */
8461 +
8462 +void
8463 +s_purgem (int ignore ATTRIBUTE_UNUSED)
8464 +{
8465 +  if (is_it_end_of_statement ())
8466 +    {
8467 +      demand_empty_rest_of_line ();
8468 +      return;
8469 +    }
8470 +
8471 +  do
8472 +    {
8473 +      char *name;
8474 +      char c;
8475 +
8476 +      SKIP_WHITESPACE ();
8477 +      name = input_line_pointer;
8478 +      c = get_symbol_end ();
8479 +      delete_macro (name);
8480 +      *input_line_pointer = c;
8481 +      SKIP_WHITESPACE ();
8482 +    }
8483 +  while (*input_line_pointer++ == ',');
8484 +
8485 +  --input_line_pointer;
8486 +  demand_empty_rest_of_line ();
8487 +}
8488 +
8489 +/* Handle the .endm/.endr pseudo-ops.  */
8490 +
8491 +static void
8492 +s_bad_end (int endr)
8493 +{
8494 +  as_warn (_(".end%c encountered without preceeding %s"),
8495 +          endr ? 'r' : 'm',
8496 +          endr ? ".rept, .irp, or .irpc" : ".macro");
8497 +  demand_empty_rest_of_line ();
8498 +}
8499 +
8500 +/* Handle the .rept pseudo-op.  */
8501 +
8502 +void
8503 +s_rept (int ignore ATTRIBUTE_UNUSED)
8504 +{
8505 +  int count;
8506 +
8507 +  count = get_absolute_expression ();
8508 +
8509 +  do_repeat (count, "REPT", "ENDR");
8510 +}
8511 +
8512 +/* This function provides a generic repeat block implementation.   It allows
8513 +   different directives to be used as the start/end keys.  */
8514 +
8515 +void
8516 +do_repeat (int count, const char *start, const char *end)
8517 +{
8518 +  sb one;
8519 +  sb many;
8520 +
8521 +  sb_new (&one);
8522 +  if (!buffer_and_nest (start, end, &one, get_line_sb))
8523 +    {
8524 +      as_bad (_("%s without %s"), start, end);
8525 +      return;
8526 +    }
8527 +
8528 +  sb_new (&many);
8529 +  while (count-- > 0)
8530 +    sb_add_sb (&many, &one);
8531 +
8532 +  sb_kill (&one);
8533 +
8534 +  input_scrub_include_sb (&many, input_line_pointer, 1);
8535 +  sb_kill (&many);
8536 +  buffer_limit = input_scrub_next_buffer (&input_line_pointer);
8537 +}
8538 +
8539 +/* Skip to end of current repeat loop; EXTRA indicates how many additional
8540 +   input buffers to skip.  Assumes that conditionals preceding the loop end
8541 +   are properly nested.
8542 +
8543 +   This function makes it easier to implement a premature "break" out of the
8544 +   loop.  The EXTRA arg accounts for other buffers we might have inserted,
8545 +   such as line substitutions.  */
8546 +
8547 +void
8548 +end_repeat (int extra)
8549 +{
8550 +  cond_exit_macro (macro_nest);
8551 +  while (extra-- >= 0)
8552 +    buffer_limit = input_scrub_next_buffer (&input_line_pointer);
8553 +}
8554 +
8555 +static void
8556 +assign_symbol (char *name, int no_reassign)
8557 +{
8558 +  symbolS *symbolP;
8559 +
8560 +  if (name[0] == '.' && name[1] == '\0')
8561 +    {
8562 +      /* Turn '. = mumble' into a .org mumble.  */
8563 +      segT segment;
8564 +      expressionS exp;
8565 +
8566 +      segment = get_known_segmented_expression (&exp);
8567 +
8568 +      if (!need_pass_2)
8569 +       do_org (segment, &exp, 0);
8570 +
8571 +      return;
8572 +    }
8573 +
8574 +  if ((symbolP = symbol_find (name)) == NULL
8575 +      && (symbolP = md_undefined_symbol (name)) == NULL)
8576 +    {
8577 +      symbolP = symbol_find_or_make (name);
8578 +#ifndef NO_LISTING
8579 +      /* When doing symbol listings, play games with dummy fragments living
8580 +        outside the normal fragment chain to record the file and line info
8581 +        for this symbol.  */
8582 +      if (listing & LISTING_SYMBOLS)
8583 +       {
8584 +         extern struct list_info_struct *listing_tail;
8585 +         fragS *dummy_frag = (fragS *) xcalloc (1, sizeof (fragS));
8586 +         dummy_frag->line = listing_tail;
8587 +         dummy_frag->fr_symbol = symbolP;
8588 +         symbol_set_frag (symbolP, dummy_frag);
8589 +       }
8590 +#endif
8591 +#ifdef OBJ_COFF
8592 +      /* "set" symbols are local unless otherwise specified.  */
8593 +      SF_SET_LOCAL (symbolP);
8594 +#endif
8595 +    }
8596 +
8597 +  /* Permit register names to be redefined.  */
8598 +  if (no_reassign
8599 +      && S_IS_DEFINED (symbolP)
8600 +      && S_GET_SEGMENT (symbolP) != reg_section)
8601 +    as_bad (_("symbol `%s' is already defined"), name);
8602 +
8603 +  pseudo_set (symbolP);
8604 +}
8605 +
8606 +/* Handle the .equ, .equiv and .set directives.  If EQUIV is 1, then
8607 +   this is .equiv, and it is an error if the symbol is already
8608 +   defined.  */
8609 +
8610 +void
8611 +s_set (int equiv)
8612 +{
8613 +  char *name;
8614 +  char delim;
8615 +  char *end_name;
8616 +
8617 +  /* Especial apologies for the random logic:
8618 +     this just grew, and could be parsed much more simply!
8619 +     Dean in haste.  */
8620 +  name = input_line_pointer;
8621 +  delim = get_symbol_end ();
8622 +  end_name = input_line_pointer;
8623 +  *end_name = delim;
8624 +
8625 +  if (name == end_name)
8626 +    {
8627 +      as_bad (_("expected symbol name"));
8628 +      ignore_rest_of_line ();
8629 +      return;
8630 +    }
8631 +
8632 +  SKIP_WHITESPACE ();
8633 +
8634 +  if (*input_line_pointer != ',')
8635 +    {
8636 +      *end_name = 0;
8637 +      as_bad (_("expected comma after \"%s\""), name);
8638 +      *end_name = delim;
8639 +      ignore_rest_of_line ();
8640 +      return;
8641 +    }
8642 +
8643 +  input_line_pointer++;
8644 +  *end_name = 0;
8645 +
8646 +  assign_symbol (name, equiv);
8647 +  *end_name = delim;
8648 +
8649 +  demand_empty_rest_of_line ();
8650 +}
8651 +
8652 +void
8653 +s_space (int mult)
8654 +{
8655 +  expressionS exp;
8656 +  expressionS val;
8657 +  char *p = 0;
8658 +  char *stop = NULL;
8659 +  char stopc;
8660 +  int bytes;
8661 +
8662 +#ifdef md_flush_pending_output
8663 +  md_flush_pending_output ();
8664 +#endif
8665 +
8666 +  if (flag_mri)
8667 +    stop = mri_comment_field (&stopc);
8668 +
8669 +  /* In m68k MRI mode, we need to align to a word boundary, unless
8670 +     this is ds.b.  */
8671 +  if (flag_m68k_mri && mult > 1)
8672 +    {
8673 +      if (now_seg == absolute_section)
8674 +       {
8675 +         abs_section_offset += abs_section_offset & 1;
8676 +         if (line_label != NULL)
8677 +           S_SET_VALUE (line_label, abs_section_offset);
8678 +       }
8679 +      else if (mri_common_symbol != NULL)
8680 +       {
8681 +         valueT val;
8682 +
8683 +         val = S_GET_VALUE (mri_common_symbol);
8684 +         if ((val & 1) != 0)
8685 +           {
8686 +             S_SET_VALUE (mri_common_symbol, val + 1);
8687 +             if (line_label != NULL)
8688 +               {
8689 +                 expressionS *symexp;
8690 +
8691 +                 symexp = symbol_get_value_expression (line_label);
8692 +                 know (symexp->X_op == O_symbol);
8693 +                 know (symexp->X_add_symbol == mri_common_symbol);
8694 +                 symexp->X_add_number += 1;
8695 +               }
8696 +           }
8697 +       }
8698 +      else
8699 +       {
8700 +         do_align (1, (char *) NULL, 0, 0);
8701 +         if (line_label != NULL)
8702 +           {
8703 +             symbol_set_frag (line_label, frag_now);
8704 +             S_SET_VALUE (line_label, frag_now_fix ());
8705 +           }
8706 +       }
8707 +    }
8708 +
8709 +  bytes = mult;
8710 +
8711 +  expression (&exp);
8712 +
8713 +  SKIP_WHITESPACE ();
8714 +  if (*input_line_pointer == ',')
8715 +    {
8716 +      ++input_line_pointer;
8717 +      expression (&val);
8718 +    }
8719 +  else
8720 +    {
8721 +      val.X_op = O_constant;
8722 +      val.X_add_number = 0;
8723 +    }
8724 +
8725 +  if (val.X_op != O_constant
8726 +      || val.X_add_number < - 0x80
8727 +      || val.X_add_number > 0xff
8728 +      || (mult != 0 && mult != 1 && val.X_add_number != 0))
8729 +    {
8730 +      if (exp.X_op != O_constant)
8731 +       as_bad (_("unsupported variable size or fill value"));
8732 +      else
8733 +       {
8734 +         offsetT i;
8735 +
8736 +         if (mult == 0)
8737 +           mult = 1;
8738 +         bytes = mult * exp.X_add_number;
8739 +         for (i = 0; i < exp.X_add_number; i++)
8740 +           emit_expr (&val, mult);
8741 +       }
8742 +    }
8743 +  else
8744 +    {
8745 +      if (exp.X_op == O_constant)
8746 +       {
8747 +         long repeat;
8748 +
8749 +         repeat = exp.X_add_number;
8750 +         if (mult)
8751 +           repeat *= mult;
8752 +         bytes = repeat;
8753 +         if (repeat <= 0)
8754 +           {
8755 +             if (!flag_mri)
8756 +               as_warn (_(".space repeat count is zero, ignored"));
8757 +             else if (repeat < 0)
8758 +               as_warn (_(".space repeat count is negative, ignored"));
8759 +             goto getout;
8760 +           }
8761 +
8762 +         /* If we are in the absolute section, just bump the offset.  */
8763 +         if (now_seg == absolute_section)
8764 +           {
8765 +             abs_section_offset += repeat;
8766 +             goto getout;
8767 +           }
8768 +
8769 +         /* If we are secretly in an MRI common section, then
8770 +            creating space just increases the size of the common
8771 +            symbol.  */
8772 +         if (mri_common_symbol != NULL)
8773 +           {
8774 +             S_SET_VALUE (mri_common_symbol,
8775 +                          S_GET_VALUE (mri_common_symbol) + repeat);
8776 +             goto getout;
8777 +           }
8778 +
8779 +         if (!need_pass_2)
8780 +           p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
8781 +                         (offsetT) repeat, (char *) 0);
8782 +       }
8783 +      else
8784 +       {
8785 +         if (now_seg == absolute_section)
8786 +           {
8787 +             as_bad (_("space allocation too complex in absolute section"));
8788 +             subseg_set (text_section, 0);
8789 +           }
8790 +
8791 +         if (mri_common_symbol != NULL)
8792 +           {
8793 +             as_bad (_("space allocation too complex in common section"));
8794 +             mri_common_symbol = NULL;
8795 +           }
8796 +
8797 +         if (!need_pass_2)
8798 +           p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
8799 +                         make_expr_symbol (&exp), (offsetT) 0, (char *) 0);
8800 +       }
8801 +
8802 +      if (p)
8803 +       *p = val.X_add_number;
8804 +    }
8805 +
8806 + getout:
8807 +
8808 +  /* In MRI mode, after an odd number of bytes, we must align to an
8809 +     even word boundary, unless the next instruction is a dc.b, ds.b
8810 +     or dcb.b.  */
8811 +  if (flag_mri && (bytes & 1) != 0)
8812 +    mri_pending_align = 1;
8813 +
8814 +  demand_empty_rest_of_line ();
8815 +
8816 +  if (flag_mri)
8817 +    mri_comment_end (stop, stopc);
8818 +}
8819 +
8820 +/* This is like s_space, but the value is a floating point number with
8821 +   the given precision.  This is for the MRI dcb.s pseudo-op and
8822 +   friends.  */
8823 +
8824 +void
8825 +s_float_space (int float_type)
8826 +{
8827 +  offsetT count;
8828 +  int flen;
8829 +  char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
8830 +  char *stop = NULL;
8831 +  char stopc;
8832 +
8833 +  if (flag_mri)
8834 +    stop = mri_comment_field (&stopc);
8835 +
8836 +  count = get_absolute_expression ();
8837 +
8838 +  SKIP_WHITESPACE ();
8839 +  if (*input_line_pointer != ',')
8840 +    {
8841 +      as_bad (_("missing value"));
8842 +      ignore_rest_of_line ();
8843 +      if (flag_mri)
8844 +       mri_comment_end (stop, stopc);
8845 +      return;
8846 +    }
8847 +
8848 +  ++input_line_pointer;
8849 +
8850 +  SKIP_WHITESPACE ();
8851 +
8852 +  /* Skip any 0{letter} that may be present.  Don't even check if the
8853 +   * letter is legal.  */
8854 +  if (input_line_pointer[0] == '0'
8855 +      && ISALPHA (input_line_pointer[1]))
8856 +    input_line_pointer += 2;
8857 +
8858 +  /* Accept :xxxx, where the x's are hex digits, for a floating point
8859 +     with the exact digits specified.  */
8860 +  if (input_line_pointer[0] == ':')
8861 +    {
8862 +      flen = hex_float (float_type, temp);
8863 +      if (flen < 0)
8864 +       {
8865 +         ignore_rest_of_line ();
8866 +         if (flag_mri)
8867 +           mri_comment_end (stop, stopc);
8868 +         return;
8869 +       }
8870 +    }
8871 +  else
8872 +    {
8873 +      char *err;
8874 +
8875 +      err = md_atof (float_type, temp, &flen);
8876 +      know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
8877 +      know (flen > 0);
8878 +      if (err)
8879 +       {
8880 +         as_bad (_("bad floating literal: %s"), err);
8881 +         ignore_rest_of_line ();
8882 +         if (flag_mri)
8883 +           mri_comment_end (stop, stopc);
8884 +         return;
8885 +       }
8886 +    }
8887 +
8888 +  while (--count >= 0)
8889 +    {
8890 +      char *p;
8891 +
8892 +      p = frag_more (flen);
8893 +      memcpy (p, temp, (unsigned int) flen);
8894 +    }
8895 +
8896 +  demand_empty_rest_of_line ();
8897 +
8898 +  if (flag_mri)
8899 +    mri_comment_end (stop, stopc);
8900 +}
8901 +
8902 +/* Handle the .struct pseudo-op, as found in MIPS assemblers.  */
8903 +
8904 +void
8905 +s_struct (int ignore ATTRIBUTE_UNUSED)
8906 +{
8907 +  char *stop = NULL;
8908 +  char stopc;
8909 +
8910 +  if (flag_mri)
8911 +    stop = mri_comment_field (&stopc);
8912 +  abs_section_offset = get_absolute_expression ();
8913 +  subseg_set (absolute_section, 0);
8914 +  demand_empty_rest_of_line ();
8915 +  if (flag_mri)
8916 +    mri_comment_end (stop, stopc);
8917 +}
8918 +
8919 +void
8920 +s_text (int ignore ATTRIBUTE_UNUSED)
8921 +{
8922 +  register int temp;
8923 +
8924 +  temp = get_absolute_expression ();
8925 +  subseg_set (text_section, (subsegT) temp);
8926 +  demand_empty_rest_of_line ();
8927 +#ifdef OBJ_VMS
8928 +  const_flag &= ~IN_DEFAULT_SECTION;
8929 +#endif
8930 +}
8931 +\f
8932 +
8933 +/* Verify that we are at the end of a line.  If not, issue an error and
8934 +   skip to EOL.  */
8935 +
8936 +void
8937 +demand_empty_rest_of_line (void)
8938 +{
8939 +  SKIP_WHITESPACE ();
8940 +  if (is_end_of_line[(unsigned char) *input_line_pointer])
8941 +    input_line_pointer++;
8942 +  else
8943 +    {
8944 +      if (ISPRINT (*input_line_pointer))
8945 +       as_bad (_("junk at end of line, first unrecognized character is `%c'"),
8946 +                *input_line_pointer);
8947 +      else
8948 +       as_bad (_("junk at end of line, first unrecognized character valued 0x%x"),
8949 +                *input_line_pointer);
8950 +      ignore_rest_of_line ();
8951 +    }
8952 +  
8953 +  /* Return pointing just after end-of-line.  */
8954 +  know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
8955 +}
8956 +
8957 +/* Silently advance to the end of line.  Use this after already having
8958 +   issued an error about something bad.  */
8959 +
8960 +void
8961 +ignore_rest_of_line (void)
8962 +{
8963 +  while (input_line_pointer < buffer_limit
8964 +        && !is_end_of_line[(unsigned char) *input_line_pointer])
8965 +    input_line_pointer++;
8966 +
8967 +  input_line_pointer++;
8968 +
8969 +  /* Return pointing just after end-of-line.  */
8970 +  know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
8971 +}
8972 +
8973 +/* Sets frag for given symbol to zero_address_frag, except when the
8974 +   symbol frag is already set to a dummy listing frag.  */
8975 +
8976 +static void
8977 +set_zero_frag (symbolS *symbolP)
8978 +{
8979 +  if (symbol_get_frag (symbolP)->fr_type != rs_dummy)
8980 +    symbol_set_frag (symbolP, &zero_address_frag);
8981 +}
8982 +
8983 +/* In: Pointer to a symbol.
8984 +       Input_line_pointer->expression.
8985 +
8986 +   Out:        Input_line_pointer->just after any whitespace after expression.
8987 +       Tried to set symbol to value of expression.
8988 +       Will change symbols type, value, and frag;  */
8989 +
8990 +void
8991 +pseudo_set (symbolS *symbolP)
8992 +{
8993 +  expressionS exp;
8994 +  segT seg;
8995 +#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
8996 +  int ext;
8997 +#endif /* OBJ_AOUT or OBJ_BOUT */
8998 +
8999 +  know (symbolP);              /* NULL pointer is logic error.  */
9000 +
9001 +  (void) expression (&exp);
9002 +
9003 +  if (exp.X_op == O_illegal)
9004 +    as_bad (_("illegal expression"));
9005 +  else if (exp.X_op == O_absent)
9006 +    as_bad (_("missing expression"));
9007 +  else if (exp.X_op == O_big)
9008 +    {
9009 +      if (exp.X_add_number > 0)
9010 +       as_bad (_("bignum invalid"));
9011 +      else
9012 +       as_bad (_("floating point number invalid"));
9013 +    }
9014 +  else if (exp.X_op == O_subtract
9015 +          && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol))
9016 +          && (symbol_get_frag (exp.X_add_symbol)
9017 +              == symbol_get_frag (exp.X_op_symbol)))
9018 +    {
9019 +      exp.X_op = O_constant;
9020 +      exp.X_add_number = (S_GET_VALUE (exp.X_add_symbol)
9021 +                         - S_GET_VALUE (exp.X_op_symbol));
9022 +    }
9023 +
9024 +  if (symbol_section_p (symbolP))
9025 +    {
9026 +      as_bad ("attempt to set value of section symbol");
9027 +      return;
9028 +    }
9029 +#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
9030 +  ext = S_IS_EXTERNAL (symbolP);
9031 +#endif /* OBJ_AOUT or OBJ_BOUT */
9032 +
9033 +  switch (exp.X_op)
9034 +    {
9035 +    case O_illegal:
9036 +    case O_absent:
9037 +    case O_big:
9038 +      exp.X_add_number = 0;
9039 +      /* Fall through.  */
9040 +    case O_constant:
9041 +      S_SET_SEGMENT (symbolP, absolute_section);
9042 +      S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
9043 +      set_zero_frag (symbolP);
9044 +      break;
9045 +
9046 +    case O_register:
9047 +      S_SET_SEGMENT (symbolP, reg_section);
9048 +      S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
9049 +      set_zero_frag (symbolP);
9050 +      break;
9051 +
9052 +    case O_symbol:
9053 +      seg = S_GET_SEGMENT (exp.X_add_symbol);
9054 +      /* For x=undef+const, create an expression symbol.
9055 +        For x=x+const, just update x except when x is an undefined symbol
9056 +        For x=defined+const, evaluate x.  */
9057 +      if (symbolP == exp.X_add_symbol
9058 +         && (seg != undefined_section
9059 +             || !symbol_constant_p (symbolP)))
9060 +       {
9061 +         *symbol_X_add_number (symbolP) += exp.X_add_number;
9062 +         break;
9063 +       }
9064 +      else if (seg != undefined_section)
9065 +       {
9066 +         symbolS *s = exp.X_add_symbol;
9067 +
9068 +         if (S_IS_COMMON (s))
9069 +           as_bad (_("`%s' can't be equated to common symbol '%s'"),
9070 +                   S_GET_NAME (symbolP), S_GET_NAME (s));
9071 +
9072 +         S_SET_SEGMENT (symbolP, seg);
9073 +         S_SET_VALUE (symbolP, exp.X_add_number + S_GET_VALUE (s));
9074 +         symbol_set_frag (symbolP, symbol_get_frag (s));
9075 +         copy_symbol_attributes (symbolP, s);
9076 +         break;
9077 +       }
9078 +      /* Fall thru */
9079 +
9080 +    default:
9081 +      /* The value is some complex expression.
9082 +        Set segment and frag back to that of a newly created symbol.  */
9083 +      S_SET_SEGMENT (symbolP, undefined_section);
9084 +      symbol_set_value_expression (symbolP, &exp);
9085 +      set_zero_frag (symbolP);
9086 +      break;
9087 +    }
9088 +
9089 +#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
9090 +  if (ext)
9091 +    S_SET_EXTERNAL (symbolP);
9092 +  else
9093 +    S_CLEAR_EXTERNAL (symbolP);
9094 +#endif /* OBJ_AOUT or OBJ_BOUT */
9095 +}
9096 +\f
9097 +/*                     cons()
9098 +
9099 +   CONStruct more frag of .bytes, or .words etc.
9100 +   Should need_pass_2 be 1 then emit no frag(s).
9101 +   This understands EXPRESSIONS.
9102 +
9103 +   Bug (?)
9104 +
9105 +   This has a split personality. We use expression() to read the
9106 +   value. We can detect if the value won't fit in a byte or word.
9107 +   But we can't detect if expression() discarded significant digits
9108 +   in the case of a long. Not worth the crocks required to fix it.  */
9109 +
9110 +/* Select a parser for cons expressions.  */
9111 +
9112 +/* Some targets need to parse the expression in various fancy ways.
9113 +   You can define TC_PARSE_CONS_EXPRESSION to do whatever you like
9114 +   (for example, the HPPA does this).  Otherwise, you can define
9115 +   BITFIELD_CONS_EXPRESSIONS to permit bitfields to be specified, or
9116 +   REPEAT_CONS_EXPRESSIONS to permit repeat counts.  If none of these
9117 +   are defined, which is the normal case, then only simple expressions
9118 +   are permitted.  */
9119 +
9120 +#ifdef TC_M68K
9121 +static void
9122 +parse_mri_cons (expressionS *exp, unsigned int nbytes);
9123 +#endif
9124 +
9125 +#ifndef TC_PARSE_CONS_EXPRESSION
9126 +#ifdef BITFIELD_CONS_EXPRESSIONS
9127 +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
9128 +static void
9129 +parse_bitfield_cons (expressionS *exp, unsigned int nbytes);
9130 +#endif
9131 +#ifdef REPEAT_CONS_EXPRESSIONS
9132 +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
9133 +static void
9134 +parse_repeat_cons (expressionS *exp, unsigned int nbytes);
9135 +#endif
9136 +
9137 +/* If we haven't gotten one yet, just call expression.  */
9138 +#ifndef TC_PARSE_CONS_EXPRESSION
9139 +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP)
9140 +#endif
9141 +#endif
9142 +
9143 +void
9144 +do_parse_cons_expression (expressionS *exp,
9145 +                         int nbytes ATTRIBUTE_UNUSED)
9146 +{
9147 +  TC_PARSE_CONS_EXPRESSION (exp, nbytes);
9148 +}
9149 +
9150 +
9151 +/* Worker to do .byte etc statements.
9152 +   Clobbers input_line_pointer and checks end-of-line.  */
9153 +
9154 +static void
9155 +cons_worker (register int nbytes,      /* 1=.byte, 2=.word, 4=.long.  */
9156 +            int rva)
9157 +{
9158 +  int c;
9159 +  expressionS exp;
9160 +  char *stop = NULL;
9161 +  char stopc;
9162 +
9163 +#ifdef md_flush_pending_output
9164 +  md_flush_pending_output ();
9165 +#endif
9166 +
9167 +  if (flag_mri)
9168 +    stop = mri_comment_field (&stopc);
9169 +
9170 +  if (is_it_end_of_statement ())
9171 +    {
9172 +      demand_empty_rest_of_line ();
9173 +      if (flag_mri)
9174 +       mri_comment_end (stop, stopc);
9175 +      return;
9176 +    }
9177 +
9178 +#ifdef TC_ADDRESS_BYTES
9179 +  if (nbytes == 0)
9180 +    nbytes = TC_ADDRESS_BYTES ();
9181 +#endif
9182 +
9183 +#ifdef md_cons_align
9184 +  md_cons_align (nbytes);
9185 +#endif
9186 +
9187 +  c = 0;
9188 +  do
9189 +    {
9190 +#ifdef TC_M68K
9191 +      if (flag_m68k_mri)
9192 +       parse_mri_cons (&exp, (unsigned int) nbytes);
9193 +      else
9194 +#endif
9195 +       TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
9196 +
9197 +      if (rva)
9198 +       {
9199 +         if (exp.X_op == O_symbol)
9200 +           exp.X_op = O_symbol_rva;
9201 +         else
9202 +           as_fatal (_("rva without symbol"));
9203 +       }
9204 +      emit_expr (&exp, (unsigned int) nbytes);
9205 +      ++c;
9206 +    }
9207 +  while (*input_line_pointer++ == ',');
9208 +
9209 +  /* In MRI mode, after an odd number of bytes, we must align to an
9210 +     even word boundary, unless the next instruction is a dc.b, ds.b
9211 +     or dcb.b.  */
9212 +  if (flag_mri && nbytes == 1 && (c & 1) != 0)
9213 +    mri_pending_align = 1;
9214 +
9215 +  input_line_pointer--;                /* Put terminator back into stream.  */
9216 +
9217 +  demand_empty_rest_of_line ();
9218 +
9219 +  if (flag_mri)
9220 +    mri_comment_end (stop, stopc);
9221 +}
9222 +
9223 +void
9224 +cons (int size)
9225 +{
9226 +  cons_worker (size, 0);
9227 +}
9228 +
9229 +void
9230 +s_rva (int size)
9231 +{
9232 +  cons_worker (size, 1);
9233 +}
9234 +
9235 +/* Put the contents of expression EXP into the object file using
9236 +   NBYTES bytes.  If need_pass_2 is 1, this does nothing.  */
9237 +
9238 +void
9239 +emit_expr (expressionS *exp, unsigned int nbytes)
9240 +{
9241 +  operatorT op;
9242 +  register char *p;
9243 +  valueT extra_digit = 0;
9244 +
9245 +  /* Don't do anything if we are going to make another pass.  */
9246 +  if (need_pass_2)
9247 +    return;
9248 +
9249 +  dot_value = frag_now_fix ();
9250 +
9251 +#ifndef NO_LISTING
9252 +#ifdef OBJ_ELF
9253 +  /* When gcc emits DWARF 1 debugging pseudo-ops, a line number will
9254 +     appear as a four byte positive constant in the .line section,
9255 +     followed by a 2 byte 0xffff.  Look for that case here.  */
9256 +  {
9257 +    static int dwarf_line = -1;
9258 +
9259 +    if (strcmp (segment_name (now_seg), ".line") != 0)
9260 +      dwarf_line = -1;
9261 +    else if (dwarf_line >= 0
9262 +            && nbytes == 2
9263 +            && exp->X_op == O_constant
9264 +            && (exp->X_add_number == -1 || exp->X_add_number == 0xffff))
9265 +      listing_source_line ((unsigned int) dwarf_line);
9266 +    else if (nbytes == 4
9267 +            && exp->X_op == O_constant
9268 +            && exp->X_add_number >= 0)
9269 +      dwarf_line = exp->X_add_number;
9270 +    else
9271 +      dwarf_line = -1;
9272 +  }
9273 +
9274 +  /* When gcc emits DWARF 1 debugging pseudo-ops, a file name will
9275 +     appear as a 2 byte TAG_compile_unit (0x11) followed by a 2 byte
9276 +     AT_sibling (0x12) followed by a four byte address of the sibling
9277 +     followed by a 2 byte AT_name (0x38) followed by the name of the
9278 +     file.  We look for that case here.  */
9279 +  {
9280 +    static int dwarf_file = 0;
9281 +
9282 +    if (strcmp (segment_name (now_seg), ".debug") != 0)
9283 +      dwarf_file = 0;
9284 +    else if (dwarf_file == 0
9285 +            && nbytes == 2
9286 +            && exp->X_op == O_constant
9287 +            && exp->X_add_number == 0x11)
9288 +      dwarf_file = 1;
9289 +    else if (dwarf_file == 1
9290 +            && nbytes == 2
9291 +            && exp->X_op == O_constant
9292 +            && exp->X_add_number == 0x12)
9293 +      dwarf_file = 2;
9294 +    else if (dwarf_file == 2
9295 +            && nbytes == 4)
9296 +      dwarf_file = 3;
9297 +    else if (dwarf_file == 3
9298 +            && nbytes == 2
9299 +            && exp->X_op == O_constant
9300 +            && exp->X_add_number == 0x38)
9301 +      dwarf_file = 4;
9302 +    else
9303 +      dwarf_file = 0;
9304 +
9305 +    /* The variable dwarf_file_string tells stringer that the string
9306 +       may be the name of the source file.  */
9307 +    if (dwarf_file == 4)
9308 +      dwarf_file_string = 1;
9309 +    else
9310 +      dwarf_file_string = 0;
9311 +  }
9312 +#endif
9313 +#endif
9314 +
9315 +  if (check_eh_frame (exp, &nbytes))
9316 +    return;
9317 +
9318 +  op = exp->X_op;
9319 +
9320 +  /* Allow `.word 0' in the absolute section.  */
9321 +  if (now_seg == absolute_section)
9322 +    {
9323 +      if (op != O_constant || exp->X_add_number != 0)
9324 +       as_bad (_("attempt to store value in absolute section"));
9325 +      abs_section_offset += nbytes;
9326 +      return;
9327 +    }
9328 +
9329 +  /* Handle a negative bignum.  */
9330 +  if (op == O_uminus
9331 +      && exp->X_add_number == 0
9332 +      && symbol_get_value_expression (exp->X_add_symbol)->X_op == O_big
9333 +      && symbol_get_value_expression (exp->X_add_symbol)->X_add_number > 0)
9334 +    {
9335 +      int i;
9336 +      unsigned long carry;
9337 +
9338 +      exp = symbol_get_value_expression (exp->X_add_symbol);
9339 +
9340 +      /* Negate the bignum: one's complement each digit and add 1.  */
9341 +      carry = 1;
9342 +      for (i = 0; i < exp->X_add_number; i++)
9343 +       {
9344 +         unsigned long next;
9345 +
9346 +         next = (((~(generic_bignum[i] & LITTLENUM_MASK))
9347 +                  & LITTLENUM_MASK)
9348 +                 + carry);
9349 +         generic_bignum[i] = next & LITTLENUM_MASK;
9350 +         carry = next >> LITTLENUM_NUMBER_OF_BITS;
9351 +       }
9352 +
9353 +      /* We can ignore any carry out, because it will be handled by
9354 +        extra_digit if it is needed.  */
9355 +
9356 +      extra_digit = (valueT) -1;
9357 +      op = O_big;
9358 +    }
9359 +
9360 +  if (op == O_absent || op == O_illegal)
9361 +    {
9362 +      as_warn (_("zero assumed for missing expression"));
9363 +      exp->X_add_number = 0;
9364 +      op = O_constant;
9365 +    }
9366 +  else if (op == O_big && exp->X_add_number <= 0)
9367 +    {
9368 +      as_bad (_("floating point number invalid"));
9369 +      exp->X_add_number = 0;
9370 +      op = O_constant;
9371 +    }
9372 +  else if (op == O_register)
9373 +    {
9374 +      as_warn (_("register value used as expression"));
9375 +      op = O_constant;
9376 +    }
9377 +
9378 +  p = frag_more ((int) nbytes);
9379 +
9380 +#ifndef WORKING_DOT_WORD
9381 +  /* If we have the difference of two symbols in a word, save it on
9382 +     the broken_words list.  See the code in write.c.  */
9383 +  if (op == O_subtract && nbytes == 2)
9384 +    {
9385 +      struct broken_word *x;
9386 +
9387 +      x = (struct broken_word *) xmalloc (sizeof (struct broken_word));
9388 +      x->next_broken_word = broken_words;
9389 +      broken_words = x;
9390 +      x->seg = now_seg;
9391 +      x->subseg = now_subseg;
9392 +      x->frag = frag_now;
9393 +      x->word_goes_here = p;
9394 +      x->dispfrag = 0;
9395 +      x->add = exp->X_add_symbol;
9396 +      x->sub = exp->X_op_symbol;
9397 +      x->addnum = exp->X_add_number;
9398 +      x->added = 0;
9399 +      x->use_jump = 0;
9400 +      new_broken_words++;
9401 +      return;
9402 +    }
9403 +#endif
9404 +
9405 +  /* If we have an integer, but the number of bytes is too large to
9406 +     pass to md_number_to_chars, handle it as a bignum.  */
9407 +  if (op == O_constant && nbytes > sizeof (valueT))
9408 +    {
9409 +      extra_digit = exp->X_unsigned ? 0 : -1;
9410 +      convert_to_bignum (exp);
9411 +      op = O_big;
9412 +    }
9413 +
9414 +  if (op == O_constant)
9415 +    {
9416 +      register valueT get;
9417 +      register valueT use;
9418 +      register valueT mask;
9419 +      valueT hibit;
9420 +      register valueT unmask;
9421 +
9422 +      /* JF << of >= number of bits in the object is undefined.  In
9423 +        particular SPARC (Sun 4) has problems.  */
9424 +      if (nbytes >= sizeof (valueT))
9425 +       {
9426 +         mask = 0;
9427 +         if (nbytes > sizeof (valueT))
9428 +           hibit = 0;
9429 +         else
9430 +           hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1);
9431 +       }
9432 +      else
9433 +       {
9434 +         /* Don't store these bits.  */
9435 +         mask = ~(valueT) 0 << (BITS_PER_CHAR * nbytes);
9436 +         hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1);
9437 +       }
9438 +
9439 +      unmask = ~mask;          /* Do store these bits.  */
9440 +
9441 +#ifdef NEVER
9442 +      "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
9443 +      mask = ~(unmask >> 1);   /* Includes sign bit now.  */
9444 +#endif
9445 +
9446 +      get = exp->X_add_number;
9447 +      use = get & unmask;
9448 +      if ((get & mask) != 0
9449 +         && ((get & mask) != mask
9450 +             || (get & hibit) == 0))
9451 +       {               /* Leading bits contain both 0s & 1s.  */
9452 +         as_warn (_("value 0x%lx truncated to 0x%lx"),
9453 +                  (unsigned long) get, (unsigned long) use);
9454 +       }
9455 +      /* Put bytes in right order.  */
9456 +      md_number_to_chars (p, use, (int) nbytes);
9457 +    }
9458 +  else if (op == O_big)
9459 +    {
9460 +      unsigned int size;
9461 +      LITTLENUM_TYPE *nums;
9462 +
9463 +      know (nbytes % CHARS_PER_LITTLENUM == 0);
9464 +
9465 +      size = exp->X_add_number * CHARS_PER_LITTLENUM;
9466 +      if (nbytes < size)
9467 +       {
9468 +         as_warn (_("bignum truncated to %d bytes"), nbytes);
9469 +         size = nbytes;
9470 +       }
9471 +
9472 +      if (target_big_endian)
9473 +       {
9474 +         while (nbytes > size)
9475 +           {
9476 +             md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM);
9477 +             nbytes -= CHARS_PER_LITTLENUM;
9478 +             p += CHARS_PER_LITTLENUM;
9479 +           }
9480 +
9481 +         nums = generic_bignum + size / CHARS_PER_LITTLENUM;
9482 +         while (size >= CHARS_PER_LITTLENUM)
9483 +           {
9484 +             --nums;
9485 +             md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
9486 +             size -= CHARS_PER_LITTLENUM;
9487 +             p += CHARS_PER_LITTLENUM;
9488 +           }
9489 +       }
9490 +      else
9491 +       {
9492 +         nums = generic_bignum;
9493 +         while (size >= CHARS_PER_LITTLENUM)
9494 +           {
9495 +             md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
9496 +             ++nums;
9497 +             size -= CHARS_PER_LITTLENUM;
9498 +             p += CHARS_PER_LITTLENUM;
9499 +             nbytes -= CHARS_PER_LITTLENUM;
9500 +           }
9501 +
9502 +         while (nbytes >= CHARS_PER_LITTLENUM)
9503 +           {
9504 +             md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM);
9505 +             nbytes -= CHARS_PER_LITTLENUM;
9506 +             p += CHARS_PER_LITTLENUM;
9507 +           }
9508 +       }
9509 +    }
9510 +  else
9511 +    {
9512 +      memset (p, 0, nbytes);
9513 +
9514 +      /* Now we need to generate a fixS to record the symbol value.
9515 +        This is easy for BFD.  For other targets it can be more
9516 +        complex.  For very complex cases (currently, the HPPA and
9517 +        NS32K), you can define TC_CONS_FIX_NEW to do whatever you
9518 +        want.  For simpler cases, you can define TC_CONS_RELOC to be
9519 +        the name of the reloc code that should be stored in the fixS.
9520 +        If neither is defined, the code uses NO_RELOC if it is
9521 +        defined, and otherwise uses 0.  */
9522 +
9523 +#ifdef BFD_ASSEMBLER
9524 +#ifdef TC_CONS_FIX_NEW
9525 +      TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
9526 +#else
9527 +      {
9528 +       bfd_reloc_code_real_type r;
9529 +
9530 +       switch (nbytes)
9531 +         {
9532 +         case 1:
9533 +           r = BFD_RELOC_8;
9534 +           break;
9535 +         case 2:
9536 +           r = BFD_RELOC_16;
9537 +           break;
9538 +         case 4:
9539 +           r = BFD_RELOC_32;
9540 +           break;
9541 +         case 8:
9542 +           r = BFD_RELOC_64;
9543 +           break;
9544 +         default:
9545 +           as_bad (_("unsupported BFD relocation size %u"), nbytes);
9546 +           r = BFD_RELOC_32;
9547 +           break;
9548 +         }
9549 +       fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp,
9550 +                    0, r);
9551 +      }
9552 +#endif
9553 +#else
9554 +#ifdef TC_CONS_FIX_NEW
9555 +      TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
9556 +#else
9557 +      /* Figure out which reloc number to use.  Use TC_CONS_RELOC if
9558 +        it is defined, otherwise use NO_RELOC if it is defined,
9559 +        otherwise use 0.  */
9560 +#ifndef TC_CONS_RELOC
9561 +#ifdef NO_RELOC
9562 +#define TC_CONS_RELOC NO_RELOC
9563 +#else
9564 +#define TC_CONS_RELOC 0
9565 +#endif
9566 +#endif
9567 +      fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 0,
9568 +                  TC_CONS_RELOC);
9569 +#endif /* TC_CONS_FIX_NEW */
9570 +#endif /* BFD_ASSEMBLER */
9571 +    }
9572 +}
9573 +\f
9574 +#ifdef BITFIELD_CONS_EXPRESSIONS
9575 +
9576 +/* i960 assemblers, (eg, asm960), allow bitfields after ".byte" as
9577 +   w:x,y:z, where w and y are bitwidths and x and y are values.  They
9578 +   then pack them all together. We do a little better in that we allow
9579 +   them in words, longs, etc. and we'll pack them in target byte order
9580 +   for you.
9581 +
9582 +   The rules are: pack least significant bit first, if a field doesn't
9583 +   entirely fit, put it in the next unit.  Overflowing the bitfield is
9584 +   explicitly *not* even a warning.  The bitwidth should be considered
9585 +   a "mask".
9586 +
9587 +   To use this function the tc-XXX.h file should define
9588 +   BITFIELD_CONS_EXPRESSIONS.  */
9589 +
9590 +static void
9591 +parse_bitfield_cons (exp, nbytes)
9592 +     expressionS *exp;
9593 +     unsigned int nbytes;
9594 +{
9595 +  unsigned int bits_available = BITS_PER_CHAR * nbytes;
9596 +  char *hold = input_line_pointer;
9597 +
9598 +  (void) expression (exp);
9599 +
9600 +  if (*input_line_pointer == ':')
9601 +    {
9602 +      /* Bitfields.  */
9603 +      long value = 0;
9604 +
9605 +      for (;;)
9606 +       {
9607 +         unsigned long width;
9608 +
9609 +         if (*input_line_pointer != ':')
9610 +           {
9611 +             input_line_pointer = hold;
9612 +             break;
9613 +           }                   /* Next piece is not a bitfield.  */
9614 +
9615 +         /* In the general case, we can't allow
9616 +            full expressions with symbol
9617 +            differences and such.  The relocation
9618 +            entries for symbols not defined in this
9619 +            assembly would require arbitrary field
9620 +            widths, positions, and masks which most
9621 +            of our current object formats don't
9622 +            support.
9623 +
9624 +            In the specific case where a symbol
9625 +            *is* defined in this assembly, we
9626 +            *could* build fixups and track it, but
9627 +            this could lead to confusion for the
9628 +            backends.  I'm lazy. I'll take any
9629 +            SEG_ABSOLUTE. I think that means that
9630 +            you can use a previous .set or
9631 +            .equ type symbol.  xoxorich.  */
9632 +
9633 +         if (exp->X_op == O_absent)
9634 +           {
9635 +             as_warn (_("using a bit field width of zero"));
9636 +             exp->X_add_number = 0;
9637 +             exp->X_op = O_constant;
9638 +           }                   /* Implied zero width bitfield.  */
9639 +
9640 +         if (exp->X_op != O_constant)
9641 +           {
9642 +             *input_line_pointer = '\0';
9643 +             as_bad (_("field width \"%s\" too complex for a bitfield"), hold);
9644 +             *input_line_pointer = ':';
9645 +             demand_empty_rest_of_line ();
9646 +             return;
9647 +           }                   /* Too complex.  */
9648 +
9649 +         if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes))
9650 +           {
9651 +             as_warn (_("field width %lu too big to fit in %d bytes: truncated to %d bits"),
9652 +                      width, nbytes, (BITS_PER_CHAR * nbytes));
9653 +             width = BITS_PER_CHAR * nbytes;
9654 +           }                   /* Too big.  */
9655 +
9656 +         if (width > bits_available)
9657 +           {
9658 +             /* FIXME-SOMEDAY: backing up and reparsing is wasteful.  */
9659 +             input_line_pointer = hold;
9660 +             exp->X_add_number = value;
9661 +             break;
9662 +           }                   /* Won't fit.  */
9663 +
9664 +         /* Skip ':'.  */
9665 +         hold = ++input_line_pointer;
9666 +
9667 +         (void) expression (exp);
9668 +         if (exp->X_op != O_constant)
9669 +           {
9670 +             char cache = *input_line_pointer;
9671 +
9672 +             *input_line_pointer = '\0';
9673 +             as_bad (_("field value \"%s\" too complex for a bitfield"), hold);
9674 +             *input_line_pointer = cache;
9675 +             demand_empty_rest_of_line ();
9676 +             return;
9677 +           }                   /* Too complex.  */
9678 +
9679 +         value |= ((~(-1 << width) & exp->X_add_number)
9680 +                   << ((BITS_PER_CHAR * nbytes) - bits_available));
9681 +
9682 +         if ((bits_available -= width) == 0
9683 +             || is_it_end_of_statement ()
9684 +             || *input_line_pointer != ',')
9685 +           {
9686 +             break;
9687 +           }                   /* All the bitfields we're gonna get.  */
9688 +
9689 +         hold = ++input_line_pointer;
9690 +         (void) expression (exp);
9691 +       }
9692 +
9693 +      exp->X_add_number = value;
9694 +      exp->X_op = O_constant;
9695 +      exp->X_unsigned = 1;
9696 +    }
9697 +}
9698 +
9699 +#endif /* BITFIELD_CONS_EXPRESSIONS */
9700 +\f
9701 +/* Handle an MRI style string expression.  */
9702 +
9703 +#ifdef TC_M68K
9704 +static void
9705 +parse_mri_cons (exp, nbytes)
9706 +     expressionS *exp;
9707 +     unsigned int nbytes;
9708 +{
9709 +  if (*input_line_pointer != '\''
9710 +      && (input_line_pointer[1] != '\''
9711 +         || (*input_line_pointer != 'A'
9712 +             && *input_line_pointer != 'E')))
9713 +    TC_PARSE_CONS_EXPRESSION (exp, nbytes);
9714 +  else
9715 +    {
9716 +      unsigned int scan;
9717 +      unsigned int result = 0;
9718 +
9719 +      /* An MRI style string.  Cut into as many bytes as will fit into
9720 +        a nbyte chunk, left justify if necessary, and separate with
9721 +        commas so we can try again later.  */
9722 +      if (*input_line_pointer == 'A')
9723 +       ++input_line_pointer;
9724 +      else if (*input_line_pointer == 'E')
9725 +       {
9726 +         as_bad (_("EBCDIC constants are not supported"));
9727 +         ++input_line_pointer;
9728 +       }
9729 +
9730 +      input_line_pointer++;
9731 +      for (scan = 0; scan < nbytes; scan++)
9732 +       {
9733 +         if (*input_line_pointer == '\'')
9734 +           {
9735 +             if (input_line_pointer[1] == '\'')
9736 +               {
9737 +                 input_line_pointer++;
9738 +               }
9739 +             else
9740 +               break;
9741 +           }
9742 +         result = (result << 8) | (*input_line_pointer++);
9743 +       }
9744 +
9745 +      /* Left justify.  */
9746 +      while (scan < nbytes)
9747 +       {
9748 +         result <<= 8;
9749 +         scan++;
9750 +       }
9751 +
9752 +      /* Create correct expression.  */
9753 +      exp->X_op = O_constant;
9754 +      exp->X_add_number = result;
9755 +
9756 +      /* Fake it so that we can read the next char too.  */
9757 +      if (input_line_pointer[0] != '\'' ||
9758 +         (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
9759 +       {
9760 +         input_line_pointer -= 2;
9761 +         input_line_pointer[0] = ',';
9762 +         input_line_pointer[1] = '\'';
9763 +       }
9764 +      else
9765 +       input_line_pointer++;
9766 +    }
9767 +}
9768 +#endif /* TC_M68K */
9769 +\f
9770 +#ifdef REPEAT_CONS_EXPRESSIONS
9771 +
9772 +/* Parse a repeat expression for cons.  This is used by the MIPS
9773 +   assembler.  The format is NUMBER:COUNT; NUMBER appears in the
9774 +   object file COUNT times.
9775 +
9776 +   To use this for a target, define REPEAT_CONS_EXPRESSIONS.  */
9777 +
9778 +static void
9779 +parse_repeat_cons (exp, nbytes)
9780 +     expressionS *exp;
9781 +     unsigned int nbytes;
9782 +{
9783 +  expressionS count;
9784 +  register int i;
9785 +
9786 +  expression (exp);
9787 +
9788 +  if (*input_line_pointer != ':')
9789 +    {
9790 +      /* No repeat count.  */
9791 +      return;
9792 +    }
9793 +
9794 +  ++input_line_pointer;
9795 +  expression (&count);
9796 +  if (count.X_op != O_constant
9797 +      || count.X_add_number <= 0)
9798 +    {
9799 +      as_warn (_("unresolvable or nonpositive repeat count; using 1"));
9800 +      return;
9801 +    }
9802 +
9803 +  /* The cons function is going to output this expression once.  So we
9804 +     output it count - 1 times.  */
9805 +  for (i = count.X_add_number - 1; i > 0; i--)
9806 +    emit_expr (exp, nbytes);
9807 +}
9808 +
9809 +#endif /* REPEAT_CONS_EXPRESSIONS */
9810 +\f
9811 +/* Parse a floating point number represented as a hex constant.  This
9812 +   permits users to specify the exact bits they want in the floating
9813 +   point number.  */
9814 +
9815 +static int
9816 +hex_float (int float_type, char *bytes)
9817 +{
9818 +  int length;
9819 +  int i;
9820 +
9821 +  switch (float_type)
9822 +    {
9823 +    case 'f':
9824 +    case 'F':
9825 +    case 's':
9826 +    case 'S':
9827 +      length = 4;
9828 +      break;
9829 +
9830 +    case 'd':
9831 +    case 'D':
9832 +    case 'r':
9833 +    case 'R':
9834 +      length = 8;
9835 +      break;
9836 +
9837 +    case 'x':
9838 +    case 'X':
9839 +      length = 12;
9840 +      break;
9841 +
9842 +    case 'p':
9843 +    case 'P':
9844 +      length = 12;
9845 +      break;
9846 +
9847 +    default:
9848 +      as_bad (_("unknown floating type type '%c'"), float_type);
9849 +      return -1;
9850 +    }
9851 +
9852 +  /* It would be nice if we could go through expression to parse the
9853 +     hex constant, but if we get a bignum it's a pain to sort it into
9854 +     the buffer correctly.  */
9855 +  i = 0;
9856 +  while (hex_p (*input_line_pointer) || *input_line_pointer == '_')
9857 +    {
9858 +      int d;
9859 +
9860 +      /* The MRI assembler accepts arbitrary underscores strewn about
9861 +        through the hex constant, so we ignore them as well.  */
9862 +      if (*input_line_pointer == '_')
9863 +       {
9864 +         ++input_line_pointer;
9865 +         continue;
9866 +       }
9867 +
9868 +      if (i >= length)
9869 +       {
9870 +         as_warn (_("floating point constant too large"));
9871 +         return -1;
9872 +       }
9873 +      d = hex_value (*input_line_pointer) << 4;
9874 +      ++input_line_pointer;
9875 +      while (*input_line_pointer == '_')
9876 +       ++input_line_pointer;
9877 +      if (hex_p (*input_line_pointer))
9878 +       {
9879 +         d += hex_value (*input_line_pointer);
9880 +         ++input_line_pointer;
9881 +       }
9882 +      if (target_big_endian)
9883 +       bytes[i] = d;
9884 +      else
9885 +       bytes[length - i - 1] = d;
9886 +      ++i;
9887 +    }
9888 +
9889 +  if (i < length)
9890 +    {
9891 +      if (target_big_endian)
9892 +       memset (bytes + i, 0, length - i);
9893 +      else
9894 +       memset (bytes, 0, length - i);
9895 +    }
9896 +
9897 +  return length;
9898 +}
9899 +
9900 +/*                     float_cons()
9901 +
9902 +   CONStruct some more frag chars of .floats .ffloats etc.
9903 +   Makes 0 or more new frags.
9904 +   If need_pass_2 == 1, no frags are emitted.
9905 +   This understands only floating literals, not expressions. Sorry.
9906 +
9907 +   A floating constant is defined by atof_generic(), except it is preceded
9908 +   by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
9909 +   reading, I decided to be incompatible. This always tries to give you
9910 +   rounded bits to the precision of the pseudo-op. Former AS did premature
9911 +   truncation, restored noisy bits instead of trailing 0s AND gave you
9912 +   a choice of 2 flavours of noise according to which of 2 floating-point
9913 +   scanners you directed AS to use.
9914 +
9915 +   In: input_line_pointer->whitespace before, or '0' of flonum.  */
9916 +
9917 +void
9918 +float_cons (/* Clobbers input_line-pointer, checks end-of-line.  */
9919 +           register int float_type     /* 'f':.ffloat ... 'F':.float ...  */)
9920 +{
9921 +  register char *p;
9922 +  int length;                  /* Number of chars in an object.  */
9923 +  register char *err;          /* Error from scanning floating literal.  */
9924 +  char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
9925 +
9926 +  if (is_it_end_of_statement ())
9927 +    {
9928 +      demand_empty_rest_of_line ();
9929 +      return;
9930 +    }
9931 +
9932 +#ifdef md_flush_pending_output
9933 +  md_flush_pending_output ();
9934 +#endif
9935 +
9936 +  do
9937 +    {
9938 +      /* input_line_pointer->1st char of a flonum (we hope!).  */
9939 +      SKIP_WHITESPACE ();
9940 +
9941 +      /* Skip any 0{letter} that may be present. Don't even check if the
9942 +        letter is legal. Someone may invent a "z" format and this routine
9943 +        has no use for such information. Lusers beware: you get
9944 +        diagnostics if your input is ill-conditioned.  */
9945 +      if (input_line_pointer[0] == '0'
9946 +         && ISALPHA (input_line_pointer[1]))
9947 +       input_line_pointer += 2;
9948 +
9949 +      /* Accept :xxxx, where the x's are hex digits, for a floating
9950 +        point with the exact digits specified.  */
9951 +      if (input_line_pointer[0] == ':')
9952 +       {
9953 +         ++input_line_pointer;
9954 +         length = hex_float (float_type, temp);
9955 +         if (length < 0)
9956 +           {
9957 +             ignore_rest_of_line ();
9958 +             return;
9959 +           }
9960 +       }
9961 +      else
9962 +       {
9963 +         err = md_atof (float_type, temp, &length);
9964 +         know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
9965 +         know (length > 0);
9966 +         if (err)
9967 +           {
9968 +             as_bad (_("bad floating literal: %s"), err);
9969 +             ignore_rest_of_line ();
9970 +             return;
9971 +           }
9972 +       }
9973 +
9974 +      if (!need_pass_2)
9975 +       {
9976 +         int count;
9977 +
9978 +         count = 1;
9979 +
9980 +#ifdef REPEAT_CONS_EXPRESSIONS
9981 +         if (*input_line_pointer == ':')
9982 +           {
9983 +             expressionS count_exp;
9984 +
9985 +             ++input_line_pointer;
9986 +             expression (&count_exp);
9987 +
9988 +             if (count_exp.X_op != O_constant
9989 +                 || count_exp.X_add_number <= 0)
9990 +               as_warn (_("unresolvable or nonpositive repeat count; using 1"));
9991 +             else
9992 +               count = count_exp.X_add_number;
9993 +           }
9994 +#endif
9995 +
9996 +         while (--count >= 0)
9997 +           {
9998 +             p = frag_more (length);
9999 +             memcpy (p, temp, (unsigned int) length);
10000 +           }
10001 +       }
10002 +      SKIP_WHITESPACE ();
10003 +    }
10004 +  while (*input_line_pointer++ == ',');
10005 +
10006 +  /* Put terminator back into stream.  */
10007 +  --input_line_pointer;
10008 +  demand_empty_rest_of_line ();
10009 +}
10010 +\f
10011 +/* Return the size of a LEB128 value.  */
10012 +
10013 +static inline int
10014 +sizeof_sleb128 (offsetT value)
10015 +{
10016 +  register int size = 0;
10017 +  register unsigned byte;
10018 +
10019 +  do
10020 +    {
10021 +      byte = (value & 0x7f);
10022 +      /* Sadly, we cannot rely on typical arithmetic right shift behaviour.
10023 +        Fortunately, we can structure things so that the extra work reduces
10024 +        to a noop on systems that do things "properly".  */
10025 +      value = (value >> 7) | ~(-(offsetT)1 >> 7);
10026 +      size += 1;
10027 +    }
10028 +  while (!(((value == 0) && ((byte & 0x40) == 0))
10029 +          || ((value == -1) && ((byte & 0x40) != 0))));
10030 +
10031 +  return size;
10032 +}
10033 +
10034 +static inline int
10035 +sizeof_uleb128 (valueT value)
10036 +{
10037 +  register int size = 0;
10038 +  register unsigned byte;
10039 +
10040 +  do
10041 +    {
10042 +      byte = (value & 0x7f);
10043 +      value >>= 7;
10044 +      size += 1;
10045 +    }
10046 +  while (value != 0);
10047 +
10048 +  return size;
10049 +}
10050 +
10051 +int
10052 +sizeof_leb128 (valueT value, int sign)
10053 +{
10054 +  if (sign)
10055 +    return sizeof_sleb128 ((offsetT) value);
10056 +  else
10057 +    return sizeof_uleb128 (value);
10058 +}
10059 +
10060 +/* Output a LEB128 value.  */
10061 +
10062 +static inline int
10063 +output_sleb128 (char *p, offsetT value)
10064 +{
10065 +  register char *orig = p;
10066 +  register int more;
10067 +
10068 +  do
10069 +    {
10070 +      unsigned byte = (value & 0x7f);
10071 +
10072 +      /* Sadly, we cannot rely on typical arithmetic right shift behaviour.
10073 +        Fortunately, we can structure things so that the extra work reduces
10074 +        to a noop on systems that do things "properly".  */
10075 +      value = (value >> 7) | ~(-(offsetT)1 >> 7);
10076 +
10077 +      more = !((((value == 0) && ((byte & 0x40) == 0))
10078 +               || ((value == -1) && ((byte & 0x40) != 0))));
10079 +      if (more)
10080 +       byte |= 0x80;
10081 +
10082 +      *p++ = byte;
10083 +    }
10084 +  while (more);
10085 +
10086 +  return p - orig;
10087 +}
10088 +
10089 +static inline int
10090 +output_uleb128 (char *p, valueT value)
10091 +{
10092 +  char *orig = p;
10093 +
10094 +  do
10095 +    {
10096 +      unsigned byte = (value & 0x7f);
10097 +      value >>= 7;
10098 +      if (value != 0)
10099 +       /* More bytes to follow.  */
10100 +       byte |= 0x80;
10101 +
10102 +      *p++ = byte;
10103 +    }
10104 +  while (value != 0);
10105 +
10106 +  return p - orig;
10107 +}
10108 +
10109 +int
10110 +output_leb128 (char *p, valueT value, int sign)
10111 +{
10112 +  if (sign)
10113 +    return output_sleb128 (p, (offsetT) value);
10114 +  else
10115 +    return output_uleb128 (p, value);
10116 +}
10117 +
10118 +/* Do the same for bignums.  We combine sizeof with output here in that
10119 +   we don't output for NULL values of P.  It isn't really as critical as
10120 +   for "normal" values that this be streamlined.  */
10121 +
10122 +static inline int
10123 +output_big_sleb128 (char *p, LITTLENUM_TYPE *bignum, int size)
10124 +{
10125 +  char *orig = p;
10126 +  valueT val = 0;
10127 +  int loaded = 0;
10128 +  unsigned byte;
10129 +
10130 +  /* Strip leading sign extensions off the bignum.  */
10131 +  while (size > 1
10132 +        && bignum[size - 1] == LITTLENUM_MASK
10133 +        && bignum[size - 2] > LITTLENUM_MASK / 2)
10134 +    size--;
10135 +
10136 +  do
10137 +    {
10138 +      /* OR in the next part of the littlenum.  */
10139 +      val |= (*bignum << loaded);
10140 +      loaded += LITTLENUM_NUMBER_OF_BITS;
10141 +      size--;
10142 +      bignum++;
10143 +
10144 +      /* Add bytes until there are less than 7 bits left in VAL
10145 +        or until every non-sign bit has been written.  */
10146 +      do
10147 +       {
10148 +         byte = val & 0x7f;
10149 +         loaded -= 7;
10150 +         val >>= 7;
10151 +         if (size > 0
10152 +             || val != ((byte & 0x40) == 0 ? 0 : ((valueT) 1 << loaded) - 1))
10153 +           byte |= 0x80;
10154 +
10155 +         if (orig)
10156 +           *p = byte;
10157 +         p++;
10158 +       }
10159 +      while ((byte & 0x80) != 0 && loaded >= 7);
10160 +    }
10161 +  while (size > 0);
10162 +
10163 +  /* Mop up any left-over bits (of which there will be less than 7).  */
10164 +  if ((byte & 0x80) != 0)
10165 +    {
10166 +      /* Sign-extend VAL.  */
10167 +      if (val & (1 << (loaded - 1)))
10168 +       val |= ~0 << loaded;
10169 +      if (orig)
10170 +       *p = val & 0x7f;
10171 +      p++;
10172 +    }
10173 +
10174 +  return p - orig;
10175 +}
10176 +
10177 +static inline int
10178 +output_big_uleb128 (char *p, LITTLENUM_TYPE *bignum, int size)
10179 +{
10180 +  char *orig = p;
10181 +  valueT val = 0;
10182 +  int loaded = 0;
10183 +  unsigned byte;
10184 +
10185 +  /* Strip leading zeros off the bignum.  */
10186 +  /* XXX: Is this needed?  */
10187 +  while (size > 0 && bignum[size - 1] == 0)
10188 +    size--;
10189 +
10190 +  do
10191 +    {
10192 +      if (loaded < 7 && size > 0)
10193 +       {
10194 +         val |= (*bignum << loaded);
10195 +         loaded += 8 * CHARS_PER_LITTLENUM;
10196 +         size--;
10197 +         bignum++;
10198 +       }
10199 +
10200 +      byte = val & 0x7f;
10201 +      loaded -= 7;
10202 +      val >>= 7;
10203 +
10204 +      if (size > 0 || val)
10205 +       byte |= 0x80;
10206 +
10207 +      if (orig)
10208 +       *p = byte;
10209 +      p++;
10210 +    }
10211 +  while (byte & 0x80);
10212 +
10213 +  return p - orig;
10214 +}
10215 +
10216 +static int
10217 +output_big_leb128 (char *p, LITTLENUM_TYPE *bignum, int size, int sign)
10218 +{
10219 +  if (sign)
10220 +    return output_big_sleb128 (p, bignum, size);
10221 +  else
10222 +    return output_big_uleb128 (p, bignum, size);
10223 +}
10224 +
10225 +/* Generate the appropriate fragments for a given expression to emit a
10226 +   leb128 value.  */
10227 +
10228 +static void
10229 +emit_leb128_expr (expressionS *exp, int sign)
10230 +{
10231 +  operatorT op = exp->X_op;
10232 +  unsigned int nbytes;
10233 +
10234 +  if (op == O_absent || op == O_illegal)
10235 +    {
10236 +      as_warn (_("zero assumed for missing expression"));
10237 +      exp->X_add_number = 0;
10238 +      op = O_constant;
10239 +    }
10240 +  else if (op == O_big && exp->X_add_number <= 0)
10241 +    {
10242 +      as_bad (_("floating point number invalid"));
10243 +      exp->X_add_number = 0;
10244 +      op = O_constant;
10245 +    }
10246 +  else if (op == O_register)
10247 +    {
10248 +      as_warn (_("register value used as expression"));
10249 +      op = O_constant;
10250 +    }
10251 +  else if (op == O_constant
10252 +          && sign
10253 +          && (exp->X_add_number < 0) != !exp->X_unsigned)
10254 +    {
10255 +      /* We're outputting a signed leb128 and the sign of X_add_number
10256 +        doesn't reflect the sign of the original value.  Convert EXP
10257 +        to a correctly-extended bignum instead.  */
10258 +      convert_to_bignum (exp);
10259 +      op = O_big;
10260 +    }
10261 +
10262 +  /* Let check_eh_frame know that data is being emitted.  nbytes == -1 is
10263 +     a signal that this is leb128 data.  It shouldn't optimize this away.  */
10264 +  nbytes = (unsigned int) -1;
10265 +  if (check_eh_frame (exp, &nbytes))
10266 +    abort ();
10267 +
10268 +  /* Let the backend know that subsequent data may be byte aligned.  */
10269 +#ifdef md_cons_align
10270 +  md_cons_align (1);
10271 +#endif
10272 +
10273 +  if (op == O_constant)
10274 +    {
10275 +      /* If we've got a constant, emit the thing directly right now.  */
10276 +
10277 +      valueT value = exp->X_add_number;
10278 +      int size;
10279 +      char *p;
10280 +
10281 +      size = sizeof_leb128 (value, sign);
10282 +      p = frag_more (size);
10283 +      output_leb128 (p, value, sign);
10284 +    }
10285 +  else if (op == O_big)
10286 +    {
10287 +      /* O_big is a different sort of constant.  */
10288 +
10289 +      int size;
10290 +      char *p;
10291 +
10292 +      size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign);
10293 +      p = frag_more (size);
10294 +      output_big_leb128 (p, generic_bignum, exp->X_add_number, sign);
10295 +    }
10296 +  else
10297 +    {
10298 +      /* Otherwise, we have to create a variable sized fragment and
10299 +        resolve things later.  */
10300 +
10301 +      frag_var (rs_leb128, sizeof_uleb128 (~(valueT) 0), 0, sign,
10302 +               make_expr_symbol (exp), 0, (char *) NULL);
10303 +    }
10304 +}
10305 +
10306 +/* Parse the .sleb128 and .uleb128 pseudos.  */
10307 +
10308 +void
10309 +s_leb128 (int sign)
10310 +{
10311 +  expressionS exp;
10312 +
10313 +#ifdef md_flush_pending_output
10314 +  md_flush_pending_output ();
10315 +#endif
10316 +
10317 +  do
10318 +    {
10319 +      expression (&exp);
10320 +      emit_leb128_expr (&exp, sign);
10321 +    }
10322 +  while (*input_line_pointer++ == ',');
10323 +
10324 +  input_line_pointer--;
10325 +  demand_empty_rest_of_line ();
10326 +}
10327 +\f
10328 +/* We read 0 or more ',' separated, double-quoted strings.
10329 +   Caller should have checked need_pass_2 is FALSE because we don't
10330 +   check it.  */
10331 +
10332 +void
10333 +stringer (/* Worker to do .ascii etc statements.  */
10334 +         /* Checks end-of-line.  */
10335 +         register int append_zero      /* 0: don't append '\0', else 1.  */)
10336 +{
10337 +  register unsigned int c;
10338 +  char *start;
10339 +
10340 +#ifdef md_flush_pending_output
10341 +  md_flush_pending_output ();
10342 +#endif
10343 +
10344 +  /* The following awkward logic is to parse ZERO or more strings,
10345 +     comma separated. Recall a string expression includes spaces
10346 +     before the opening '\"' and spaces after the closing '\"'.
10347 +     We fake a leading ',' if there is (supposed to be)
10348 +     a 1st, expression. We keep demanding expressions for each ','.  */
10349 +  if (is_it_end_of_statement ())
10350 +    {
10351 +      c = 0;                   /* Skip loop.  */
10352 +      ++input_line_pointer;    /* Compensate for end of loop.  */
10353 +    }
10354 +  else
10355 +    {
10356 +      c = ',';                 /* Do loop.  */
10357 +    }
10358 +  /* If we have been switched into the abs_section then we
10359 +     will not have an obstack onto which we can hang strings.  */
10360 +  if (now_seg == absolute_section)
10361 +    {
10362 +      as_bad (_("strings must be placed into a section"));
10363 +      c = 0;
10364 +      ignore_rest_of_line ();
10365 +    }
10366 +
10367 +  while (c == ',' || c == '<' || c == '"')
10368 +    {
10369 +      SKIP_WHITESPACE ();
10370 +      switch (*input_line_pointer)
10371 +       {
10372 +       case '\"':
10373 +         ++input_line_pointer; /*->1st char of string.  */
10374 +         start = input_line_pointer;
10375 +         while (is_a_char (c = next_char_of_string ()))
10376 +           {
10377 +             FRAG_APPEND_1_CHAR (c);
10378 +           }
10379 +         if (append_zero)
10380 +           {
10381 +             FRAG_APPEND_1_CHAR (0);
10382 +           }
10383 +         know (input_line_pointer[-1] == '\"');
10384 +
10385 +#ifndef NO_LISTING
10386 +#ifdef OBJ_ELF
10387 +         /* In ELF, when gcc is emitting DWARF 1 debugging output, it
10388 +            will emit .string with a filename in the .debug section
10389 +            after a sequence of constants.  See the comment in
10390 +            emit_expr for the sequence.  emit_expr will set
10391 +            dwarf_file_string to non-zero if this string might be a
10392 +            source file name.  */
10393 +         if (strcmp (segment_name (now_seg), ".debug") != 0)
10394 +           dwarf_file_string = 0;
10395 +         else if (dwarf_file_string)
10396 +           {
10397 +             c = input_line_pointer[-1];
10398 +             input_line_pointer[-1] = '\0';
10399 +             listing_source_file (start);
10400 +             input_line_pointer[-1] = c;
10401 +           }
10402 +#endif
10403 +#endif
10404 +
10405 +         break;
10406 +       case '<':
10407 +         input_line_pointer++;
10408 +         c = get_single_number ();
10409 +         FRAG_APPEND_1_CHAR (c);
10410 +         if (*input_line_pointer != '>')
10411 +           {
10412 +             as_bad (_("expected <nn>"));
10413 +           }
10414 +         input_line_pointer++;
10415 +         break;
10416 +       case ',':
10417 +         input_line_pointer++;
10418 +         break;
10419 +       }
10420 +      SKIP_WHITESPACE ();
10421 +      c = *input_line_pointer;
10422 +    }
10423 +
10424 +  demand_empty_rest_of_line ();
10425 +}                              /* stringer() */
10426 +\f
10427 +/* FIXME-SOMEDAY: I had trouble here on characters with the
10428 +    high bits set.  We'll probably also have trouble with
10429 +    multibyte chars, wide chars, etc.  Also be careful about
10430 +    returning values bigger than 1 byte.  xoxorich.  */
10431 +
10432 +unsigned int
10433 +next_char_of_string (void)
10434 +{
10435 +  register unsigned int c;
10436 +
10437 +  c = *input_line_pointer++ & CHAR_MASK;
10438 +  switch (c)
10439 +    {
10440 +    case '\"':
10441 +      c = NOT_A_CHAR;
10442 +      break;
10443 +
10444 +    case '\n':
10445 +      as_warn (_("unterminated string; newline inserted"));
10446 +      bump_line_counters ();
10447 +      break;
10448 +
10449 +#ifndef NO_STRING_ESCAPES
10450 +    case '\\':
10451 +      switch (c = *input_line_pointer++)
10452 +       {
10453 +       case 'b':
10454 +         c = '\b';
10455 +         break;
10456 +
10457 +       case 'f':
10458 +         c = '\f';
10459 +         break;
10460 +
10461 +       case 'n':
10462 +         c = '\n';
10463 +         break;
10464 +
10465 +       case 'r':
10466 +         c = '\r';
10467 +         break;
10468 +
10469 +       case 't':
10470 +         c = '\t';
10471 +         break;
10472 +
10473 +       case 'v':
10474 +         c = '\013';
10475 +         break;
10476 +
10477 +       case '\\':
10478 +       case '"':
10479 +         break;                /* As itself.  */
10480 +
10481 +       case '0':
10482 +       case '1':
10483 +       case '2':
10484 +       case '3':
10485 +       case '4':
10486 +       case '5':
10487 +       case '6':
10488 +       case '7':
10489 +       case '8':
10490 +       case '9':
10491 +         {
10492 +           long number;
10493 +           int i;
10494 +
10495 +           for (i = 0, number = 0;
10496 +                ISDIGIT (c) && i < 3;
10497 +                c = *input_line_pointer++, i++)
10498 +             {
10499 +               number = number * 8 + c - '0';
10500 +             }
10501 +
10502 +           c = number & 0xff;
10503 +         }
10504 +         --input_line_pointer;
10505 +         break;
10506 +
10507 +       case 'x':
10508 +       case 'X':
10509 +         {
10510 +           long number;
10511 +
10512 +           number = 0;
10513 +           c = *input_line_pointer++;
10514 +           while (ISXDIGIT (c))
10515 +             {
10516 +               if (ISDIGIT (c))
10517 +                 number = number * 16 + c - '0';
10518 +               else if (ISUPPER (c))
10519 +                 number = number * 16 + c - 'A' + 10;
10520 +               else
10521 +                 number = number * 16 + c - 'a' + 10;
10522 +               c = *input_line_pointer++;
10523 +             }
10524 +           c = number & 0xff;
10525 +           --input_line_pointer;
10526 +         }
10527 +         break;
10528 +
10529 +       case '\n':
10530 +         /* To be compatible with BSD 4.2 as: give the luser a linefeed!!  */
10531 +         as_warn (_("unterminated string; newline inserted"));
10532 +         c = '\n';
10533 +         bump_line_counters ();
10534 +         break;
10535 +
10536 +       default:
10537 +
10538 +#ifdef ONLY_STANDARD_ESCAPES
10539 +         as_bad (_("bad escaped character in string"));
10540 +         c = '?';
10541 +#endif /* ONLY_STANDARD_ESCAPES */
10542 +
10543 +         break;
10544 +       }
10545 +      break;
10546 +#endif /* ! defined (NO_STRING_ESCAPES) */
10547 +
10548 +    default:
10549 +      break;
10550 +    }
10551 +  return (c);
10552 +}
10553 +\f
10554 +static segT
10555 +get_segmented_expression (register expressionS *expP)
10556 +{
10557 +  register segT retval;
10558 +
10559 +  retval = expression (expP);
10560 +  if (expP->X_op == O_illegal
10561 +      || expP->X_op == O_absent
10562 +      || expP->X_op == O_big)
10563 +    {
10564 +      as_bad (_("expected address expression"));
10565 +      expP->X_op = O_constant;
10566 +      expP->X_add_number = 0;
10567 +      retval = absolute_section;
10568 +    }
10569 +  return retval;
10570 +}
10571 +
10572 +static segT
10573 +get_known_segmented_expression (register expressionS *expP)
10574 +{
10575 +  register segT retval;
10576 +
10577 +  if ((retval = get_segmented_expression (expP)) == undefined_section)
10578 +    {
10579 +      /* There is no easy way to extract the undefined symbol from the
10580 +        expression.  */
10581 +      if (expP->X_add_symbol != NULL
10582 +         && S_GET_SEGMENT (expP->X_add_symbol) != expr_section)
10583 +       as_warn (_("symbol \"%s\" undefined; zero assumed"),
10584 +                S_GET_NAME (expP->X_add_symbol));
10585 +      else
10586 +       as_warn (_("some symbol undefined; zero assumed"));
10587 +      retval = absolute_section;
10588 +      expP->X_op = O_constant;
10589 +      expP->X_add_number = 0;
10590 +    }
10591 +  know (retval == absolute_section || SEG_NORMAL (retval));
10592 +  return (retval);
10593 +}
10594 +
10595 +char                           /* Return terminator.  */
10596 +get_absolute_expression_and_terminator (long *val_pointer /* Return value of expression.  */)
10597 +{
10598 +  /* FIXME: val_pointer should probably be offsetT *.  */
10599 +  *val_pointer = (long) get_absolute_expression ();
10600 +  return (*input_line_pointer++);
10601 +}
10602 +\f
10603 +/* Like demand_copy_string, but return NULL if the string contains any '\0's.
10604 +   Give a warning if that happens.  */
10605 +
10606 +char *
10607 +demand_copy_C_string (int *len_pointer)
10608 +{
10609 +  register char *s;
10610 +
10611 +  if ((s = demand_copy_string (len_pointer)) != 0)
10612 +    {
10613 +      register int len;
10614 +
10615 +      for (len = *len_pointer; len > 0; len--)
10616 +       {
10617 +         if (*s == 0)
10618 +           {
10619 +             s = 0;
10620 +             len = 1;
10621 +             *len_pointer = 0;
10622 +             as_bad (_("this string may not contain \'\\0\'"));
10623 +           }
10624 +       }
10625 +    }
10626 +
10627 +  return s;
10628 +}
10629 +\f
10630 +/* Demand string, but return a safe (=private) copy of the string.
10631 +   Return NULL if we can't read a string here.  */
10632 +
10633 +char *
10634 +demand_copy_string (int *lenP)
10635 +{
10636 +  register unsigned int c;
10637 +  register int len;
10638 +  char *retval;
10639 +
10640 +  len = 0;
10641 +  SKIP_WHITESPACE ();
10642 +  if (*input_line_pointer == '\"')
10643 +    {
10644 +      input_line_pointer++;    /* Skip opening quote.  */
10645 +
10646 +      while (is_a_char (c = next_char_of_string ()))
10647 +       {
10648 +         obstack_1grow (&notes, c);
10649 +         len++;
10650 +       }
10651 +      /* JF this next line is so demand_copy_C_string will return a
10652 +        null terminated string.  */
10653 +      obstack_1grow (&notes, '\0');
10654 +      retval = obstack_finish (&notes);
10655 +    }
10656 +  else
10657 +    {
10658 +      as_bad (_("missing string"));
10659 +      retval = NULL;
10660 +      ignore_rest_of_line ();
10661 +    }
10662 +  *lenP = len;
10663 +  return (retval);
10664 +}
10665 +\f
10666 +/* In: Input_line_pointer->next character.
10667 +
10668 +   Do: Skip input_line_pointer over all whitespace.
10669 +
10670 +   Out:        1 if input_line_pointer->end-of-line.  */
10671 +
10672 +int
10673 +is_it_end_of_statement (void)
10674 +{
10675 +  SKIP_WHITESPACE ();
10676 +  return (is_end_of_line[(unsigned char) *input_line_pointer]);
10677 +}
10678 +
10679 +void
10680 +equals (char *sym_name, int reassign)
10681 +{
10682 +  char *stop = NULL;
10683 +  char stopc;
10684 +
10685 +  input_line_pointer++;
10686 +  if (*input_line_pointer == '=')
10687 +    input_line_pointer++;
10688 +
10689 +  while (*input_line_pointer == ' ' || *input_line_pointer == '\t')
10690 +    input_line_pointer++;
10691 +
10692 +  if (flag_mri)
10693 +    stop = mri_comment_field (&stopc);
10694 +
10695 +  assign_symbol (sym_name, !reassign);
10696 +
10697 +  if (flag_mri)
10698 +    {
10699 +      demand_empty_rest_of_line ();
10700 +      mri_comment_end (stop, stopc);
10701 +    }
10702 +}
10703 +
10704 +/* .incbin -- include a file verbatim at the current location.  */
10705 +
10706 +void
10707 +s_incbin (int x ATTRIBUTE_UNUSED)
10708 +{
10709 +  FILE * binfile;
10710 +  char * path;
10711 +  char * filename;
10712 +  char * binfrag;
10713 +  long   skip = 0;
10714 +  long   count = 0;
10715 +  long   bytes;
10716 +  int    len;
10717 +
10718 +#ifdef md_flush_pending_output
10719 +  md_flush_pending_output ();
10720 +#endif
10721 +
10722 +  SKIP_WHITESPACE ();
10723 +  filename = demand_copy_string (& len);
10724 +  if (filename == NULL)
10725 +    return;
10726 +
10727 +  SKIP_WHITESPACE ();
10728 +
10729 +  /* Look for optional skip and count.  */
10730 +  if (* input_line_pointer == ',')
10731 +    {
10732 +      ++ input_line_pointer;
10733 +      skip = get_absolute_expression ();
10734 +
10735 +      SKIP_WHITESPACE ();
10736 +
10737 +      if (* input_line_pointer == ',')
10738 +       {
10739 +         ++ input_line_pointer;
10740 +
10741 +         count = get_absolute_expression ();
10742 +         if (count == 0)
10743 +           as_warn (_(".incbin count zero, ignoring `%s'"), filename);
10744 +
10745 +         SKIP_WHITESPACE ();
10746 +       }
10747 +    }
10748 +
10749 +  demand_empty_rest_of_line ();
10750 +
10751 +  /* Try opening absolute path first, then try include dirs.  */
10752 +  binfile = fopen (filename, FOPEN_RB);
10753 +  if (binfile == NULL)
10754 +    {
10755 +      int i;
10756 +
10757 +      path = xmalloc ((unsigned long) len + include_dir_maxlen + 5);
10758 +
10759 +      for (i = 0; i < include_dir_count; i++)
10760 +       {
10761 +         sprintf (path, "%s/%s", include_dirs[i], filename);
10762 +
10763 +         binfile = fopen (path, FOPEN_RB);
10764 +         if (binfile != NULL)
10765 +           break;
10766 +       }
10767 +
10768 +      if (binfile == NULL)
10769 +       as_bad (_("file not found: %s"), filename);
10770 +    }
10771 +  else
10772 +    path = xstrdup (filename);
10773 +
10774 +  if (binfile)
10775 +    {
10776 +      long   file_len;
10777 +
10778 +      register_dependency (path);
10779 +
10780 +      /* Compute the length of the file.  */
10781 +      if (fseek (binfile, 0, SEEK_END) != 0)
10782 +       {
10783 +         as_bad (_("seek to end of .incbin file failed `%s'"), path);
10784 +         goto done;
10785 +       }
10786 +      file_len = ftell (binfile);
10787 +
10788 +      /* If a count was not specified use the remainder of the file.  */
10789 +      if (count == 0)
10790 +       count = file_len - skip;
10791 +
10792 +      if (skip < 0 || count < 0 || file_len < 0 || skip + count > file_len)
10793 +       {
10794 +         as_bad (_("skip (%ld) or count (%ld) invalid for file size (%ld)"),
10795 +                 skip, count, file_len);
10796 +         goto done;
10797 +       }
10798 +
10799 +      if (fseek (binfile, skip, SEEK_SET) != 0)
10800 +       {
10801 +         as_bad (_("could not skip to %ld in file `%s'"), skip, path);
10802 +         goto done;
10803 +       }
10804 +
10805 +      /* Allocate frag space and store file contents in it.  */
10806 +      binfrag = frag_more (count);
10807 +
10808 +      bytes = fread (binfrag, 1, count, binfile);
10809 +      if (bytes < count)
10810 +       as_warn (_("truncated file `%s', %ld of %ld bytes read"),
10811 +                path, bytes, count);
10812 +    }
10813 +done:
10814 +  if (binfile != NULL)
10815 +    fclose (binfile);
10816 +  if (path)
10817 +    free (path);
10818 +}
10819 +
10820 +/* .include -- include a file at this point.  */
10821 +
10822 +void
10823 +s_include (int arg ATTRIBUTE_UNUSED)
10824 +{
10825 +  char *filename;
10826 +  int i;
10827 +  FILE *try;
10828 +  char *path;
10829 +
10830 +  if (!flag_m68k_mri)
10831 +    {
10832 +      filename = demand_copy_string (&i);
10833 +      if (filename == NULL)
10834 +       {
10835 +         /* demand_copy_string has already printed an error and
10836 +            called ignore_rest_of_line.  */
10837 +         return;
10838 +       }
10839 +    }
10840 +  else
10841 +    {
10842 +      SKIP_WHITESPACE ();
10843 +      i = 0;
10844 +      while (!is_end_of_line[(unsigned char) *input_line_pointer]
10845 +            && *input_line_pointer != ' '
10846 +            && *input_line_pointer != '\t')
10847 +       {
10848 +         obstack_1grow (&notes, *input_line_pointer);
10849 +         ++input_line_pointer;
10850 +         ++i;
10851 +       }
10852 +
10853 +      obstack_1grow (&notes, '\0');
10854 +      filename = obstack_finish (&notes);
10855 +      while (!is_end_of_line[(unsigned char) *input_line_pointer])
10856 +       ++input_line_pointer;
10857 +    }
10858 +
10859 +  demand_empty_rest_of_line ();
10860 +  path = xmalloc ((unsigned long) i + include_dir_maxlen + 5 /* slop */ );
10861 +
10862 +  for (i = 0; i < include_dir_count; i++)
10863 +    {
10864 +      strcpy (path, include_dirs[i]);
10865 +      strcat (path, "/");
10866 +      strcat (path, filename);
10867 +      if (0 != (try = fopen (path, FOPEN_RT)))
10868 +       {
10869 +         fclose (try);
10870 +         goto gotit;
10871 +       }
10872 +    }
10873 +
10874 +  free (path);
10875 +  path = filename;
10876 +gotit:
10877 +  /* malloc Storage leak when file is found on path.  FIXME-SOMEDAY.  */
10878 +  register_dependency (path);
10879 +  input_scrub_insert_file (path);
10880 +}
10881 +
10882 +void
10883 +add_include_dir (char *path)
10884 +{
10885 +  int i;
10886 +
10887 +  if (include_dir_count == 0)
10888 +    {
10889 +      include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs));
10890 +      include_dirs[0] = ".";   /* Current dir.  */
10891 +      include_dir_count = 2;
10892 +    }
10893 +  else
10894 +    {
10895 +      include_dir_count++;
10896 +      include_dirs =
10897 +       (char **) realloc (include_dirs,
10898 +                          include_dir_count * sizeof (*include_dirs));
10899 +    }
10900 +
10901 +  include_dirs[include_dir_count - 1] = path;  /* New one.  */
10902 +
10903 +  i = strlen (path);
10904 +  if (i > include_dir_maxlen)
10905 +    include_dir_maxlen = i;
10906 +}
10907 +\f
10908 +/* Output debugging information to denote the source file.  */
10909 +
10910 +static void
10911 +generate_file_debug (void)
10912 +{
10913 +  if (debug_type == DEBUG_STABS)
10914 +    stabs_generate_asm_file ();
10915 +}
10916 +
10917 +/* Output line number debugging information for the current source line.  */
10918 +
10919 +void
10920 +generate_lineno_debug (void)
10921 +{
10922 +  switch (debug_type)
10923 +    {
10924 +    case DEBUG_UNSPECIFIED:
10925 +    case DEBUG_NONE:
10926 +    case DEBUG_DWARF:
10927 +      break;
10928 +    case DEBUG_STABS:
10929 +      stabs_generate_asm_lineno ();
10930 +      break;
10931 +    case DEBUG_ECOFF:
10932 +      ecoff_generate_asm_lineno ();
10933 +      break;
10934 +    case DEBUG_DWARF2:
10935 +      /* ??? We could here indicate to dwarf2dbg.c that something
10936 +        has changed.  However, since there is additional backend
10937 +        support that is required (calling dwarf2_emit_insn), we
10938 +        let dwarf2dbg.c call as_where on its own.  */
10939 +      break;
10940 +    }
10941 +}
10942 +
10943 +/* Output debugging information to mark a function entry point or end point.
10944 +   END_P is zero for .func, and non-zero for .endfunc.  */
10945 +
10946 +void
10947 +s_func (int end_p)
10948 +{
10949 +  do_s_func (end_p, NULL);
10950 +}
10951 +
10952 +/* Subroutine of s_func so targets can choose a different default prefix.
10953 +   If DEFAULT_PREFIX is NULL, use the target's "leading char".  */
10954 +
10955 +static void
10956 +do_s_func (int end_p, const char *default_prefix)
10957 +{
10958 +  /* Record the current function so that we can issue an error message for
10959 +     misplaced .func,.endfunc, and also so that .endfunc needs no
10960 +     arguments.  */
10961 +  static char *current_name;
10962 +  static char *current_label;
10963 +
10964 +  if (end_p)
10965 +    {
10966 +      if (current_name == NULL)
10967 +       {
10968 +         as_bad (_("missing .func"));
10969 +         ignore_rest_of_line ();
10970 +         return;
10971 +       }
10972 +
10973 +      if (debug_type == DEBUG_STABS)
10974 +       stabs_generate_asm_endfunc (current_name, current_label);
10975 +
10976 +      current_name = current_label = NULL;
10977 +    }
10978 +  else /* ! end_p */
10979 +    {
10980 +      char *name, *label;
10981 +      char delim1, delim2;
10982 +
10983 +      if (current_name != NULL)
10984 +       {
10985 +         as_bad (_(".endfunc missing for previous .func"));
10986 +         ignore_rest_of_line ();
10987 +         return;
10988 +       }
10989 +
10990 +      name = input_line_pointer;
10991 +      delim1 = get_symbol_end ();
10992 +      name = xstrdup (name);
10993 +      *input_line_pointer = delim1;
10994 +      SKIP_WHITESPACE ();
10995 +      if (*input_line_pointer != ',')
10996 +       {
10997 +         if (default_prefix)
10998 +           asprintf (&label, "%s%s", default_prefix, name);
10999 +         else
11000 +           {
11001 +             char leading_char = 0;
11002 +#ifdef BFD_ASSEMBLER
11003 +             leading_char = bfd_get_symbol_leading_char (stdoutput);
11004 +#endif
11005 +             /* Missing entry point, use function's name with the leading
11006 +                char prepended.  */
11007 +             if (leading_char)
11008 +               asprintf (&label, "%c%s", leading_char, name);
11009 +             else
11010 +               label = name;
11011 +           }
11012 +       }
11013 +      else
11014 +       {
11015 +         ++input_line_pointer;
11016 +         SKIP_WHITESPACE ();
11017 +         label = input_line_pointer;
11018 +         delim2 = get_symbol_end ();
11019 +         label = xstrdup (label);
11020 +         *input_line_pointer = delim2;
11021 +       }
11022 +
11023 +      if (debug_type == DEBUG_STABS)
11024 +       stabs_generate_asm_func (name, label);
11025 +
11026 +      current_name = name;
11027 +      current_label = label;
11028 +    }
11029 +
11030 +  demand_empty_rest_of_line ();
11031 +}
11032 +\f
11033 +void
11034 +s_ignore (int arg ATTRIBUTE_UNUSED)
11035 +{
11036 +  ignore_rest_of_line ();
11037 +}
11038 +
11039 +void
11040 +read_print_statistics (FILE *file)
11041 +{
11042 +  hash_print_statistics (file, "pseudo-op table", po_hash);
11043 +}
11044 +
11045 +/* Inserts the given line into the input stream.
11046 +
11047 +   This call avoids macro/conditionals nesting checking, since the contents of
11048 +   the line are assumed to replace the contents of a line already scanned.
11049 +
11050 +   An appropriate use of this function would be substitution of input lines when
11051 +   called by md_start_line_hook().  The given line is assumed to already be
11052 +   properly scrubbed.  */
11053 +
11054 +void
11055 +input_scrub_insert_line (const char *line)
11056 +{
11057 +  sb newline;
11058 +  sb_new (&newline);
11059 +  sb_add_string (&newline, line);
11060 +  input_scrub_include_sb (&newline, input_line_pointer, 0);
11061 +  sb_kill (&newline);
11062 +  buffer_limit = input_scrub_next_buffer (&input_line_pointer);
11063 +}
11064 +
11065 +/* Insert a file into the input stream; the path must resolve to an actual
11066 +   file; no include path searching or dependency registering is performed.  */
11067 +
11068 +void
11069 +input_scrub_insert_file (char *path)
11070 +{
11071 +  input_scrub_include_file (path, input_line_pointer);
11072 +  buffer_limit = input_scrub_next_buffer (&input_line_pointer);
11073 +}
11074 +
11075 +/* Find the end of a line, considering quotation and escaping of quotes.  */
11076 +
11077 +#if !defined(TC_SINGLE_QUOTE_STRINGS) && defined(SINGLE_QUOTE_STRINGS)
11078 +# define TC_SINGLE_QUOTE_STRINGS 1
11079 +#endif
11080 +
11081 +static char *
11082 +_find_end_of_line (char *s, int mri_string, int insn ATTRIBUTE_UNUSED)
11083 +{
11084 +  char inquote = '\0';
11085 +  int inescape = 0;
11086 +
11087 +  while (!is_end_of_line[(unsigned char) *s]
11088 +        || (inquote && !ISCNTRL (*s))
11089 +        || (inquote == '\'' && flag_mri)
11090 +#ifdef TC_EOL_IN_INSN
11091 +        || (insn && TC_EOL_IN_INSN (s))
11092 +#endif
11093 +       )
11094 +    {
11095 +      if (mri_string && *s == '\'')
11096 +       inquote ^= *s;
11097 +      else if (inescape)
11098 +       inescape = 0;
11099 +      else if (*s == '\\')
11100 +       inescape = 1;
11101 +      else if (!inquote
11102 +              ? *s == '"'
11103 +#ifdef TC_SINGLE_QUOTE_STRINGS
11104 +                || (TC_SINGLE_QUOTE_STRINGS && *s == '\'')
11105 +#endif
11106 +              : *s == inquote)
11107 +       inquote ^= *s;
11108 +      ++s;
11109 +    }
11110 +  if (inquote)
11111 +    as_warn (_("missing closing `%c'"), inquote);
11112 +  if (inescape)
11113 +    as_warn (_("stray `\\'"));
11114 +  return s;
11115 +}
11116 +
11117 +char *
11118 +find_end_of_line (char *s, int mri_string)
11119 +{
11120 +  return _find_end_of_line (s, mri_string, 0);
11121 +}
This page took 1.332646 seconds and 3 git commands to generate.